下面你这段程序中,Object不用static 修饰时不会产生死锁,加上static就会产生死锁,为什么会这样呢?
public class TestDeadLock implements Runnable{
static Object o1 = new Object(); //在Object前面加static与不加对synchronized有什么影响,为什么执行结果不一样
static Object o2 = new Object(); //synchronized参数都可以是什么
public int flag = 0;
public static void main(String[] args){
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 = new TestDeadLock();
td1.flag=1;
td2.flag=0;
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
t1.start();
t2.start();
}
public void run(){
System.out.println("flag="+flag);
if(flag==0){
synchronized(o1){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(o2){
System.out.println("hello");
}
}
}
if(flag==1){
synchronized(o2){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(o1){
System.out.println("ok");
}
}
}
}
}
你在锁定o1的代码块内锁定o2,在锁定o2的代码块内锁定o1
因此,如果两个线程并发各自锁住了o1 o2,并且试图去锁对方,那么程序死锁
而不加static,每个线程有一个自己的实例,锁的不是同一个o1 o2
1.synchronized修饰一个方法或者一个代码块,能够保证在同一时刻最多只有一个线程执行该段代码。是不可以修饰变量的
2.static变量时类层次的变量,也就是说所有的实例看到的static变量都是同一个,各个实例访问的时候,会出现竞争;非静态对象是实例变量,各个实例都有各自的变量,互不打扰
3.产生死锁的四个必要条件:(1) 互斥条件:一个资源每次只能被一个进程使用。(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
4.你的问题就等于是有两个资源o1,o2,然后两个进程访问这两个资源。然后你的访问资源方式符合了请求和保持条件
类的静态成员为类的所有实例所共享
我大概清楚你的问题了,你参考一下:
// 我直接根据main方法来给你解释一下这里static的作用
// 1.你声明了两个静态变量
static Object o1 = new Object();
static Object o2 = new Object();
// 2.在main方法中,你虽然实例化了两个td实例,但是两个td实例还是对应只有两个静态变量o1,o2,即td1,td2,共用o1,o2
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 = new TestDeadLock();
// 3.你虽然给t1,t2传了不同的两个td实例,但是你run方法实际上操作的是o1,o2变量。
// 如果是静态变量就表示操作的是同一个o1,o2,即会发生死锁。
// 如果你不加static修饰符,则表示为实例变量,那o1,o2就会各自有两个实例变量,那run方法操作的就不是同一个o1,o2,即不会发生死锁。
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
加上static之后,一个assambly共用一个object
没加的话,每个thread 新建一个 object
只有一份,大家每一调用就会改变
static 就不 new 了 .......
简单来讲就是这一个意思
多谢各位大神,小弟明朗了,好像只能采纳一个,就按时间来吧