下面这个为什么会死锁?执行的方法不同啊?谢谢package deadlock;class A{
public synchronized void say(B b ){
System.out.println("In A class, say method, thread = "+Thread.currentThread().getName());
System.out.println("A类中进");
b.last();
}
synchronized void last(){
System.out.println("In A class, last method, thread = "+Thread.currentThread().getName());
System.out.println("b 结束");
}
}
class B{
public synchronized void say(A a){
System.out.println("In B class, say method, thread = "+Thread.currentThread().getName());
System.out.println("B类中进 ");
a.last();
}
synchronized void last(){
System.out.println("In B class, last method, thread = "+Thread.currentThread().getName());
System.out.println("a 结束");
}
}
public class DeadlockDemo implements Runnable {
A a = new A();
B b = new B();
public DeadlockDemo(){
System.out.println("In constructor thread = "+Thread.currentThread().getName());
new Thread(this).start();
b.say(a);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("In main current thread = "+Thread.currentThread().getName());
new DeadlockDemo();
} @Override
public void run() {
// TODO Auto-generated method stub
a.say(b);
}}
public synchronized void say(B b ){
System.out.println("In A class, say method, thread = "+Thread.currentThread().getName());
System.out.println("A类中进");
b.last();
}
synchronized void last(){
System.out.println("In A class, last method, thread = "+Thread.currentThread().getName());
System.out.println("b 结束");
}
}
class B{
public synchronized void say(A a){
System.out.println("In B class, say method, thread = "+Thread.currentThread().getName());
System.out.println("B类中进 ");
a.last();
}
synchronized void last(){
System.out.println("In B class, last method, thread = "+Thread.currentThread().getName());
System.out.println("a 结束");
}
}
public class DeadlockDemo implements Runnable {
A a = new A();
B b = new B();
public DeadlockDemo(){
System.out.println("In constructor thread = "+Thread.currentThread().getName());
new Thread(this).start();
b.say(a);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("In main current thread = "+Thread.currentThread().getName());
new DeadlockDemo();
} @Override
public void run() {
// TODO Auto-generated method stub
a.say(b);
}}
解决方案 »
- 关于spring security3 重写 UserDetails
- session 丢失
- 求助,eclipse source-》override/implement method 下需要覆盖的方法显示不全
- listener问题
- 各路兄弟救救我吧~~一个lomboz插件折腾我4 5天了
- 跪求!!! hibernate 创建Configuration().configure(/hibernate.cfg.xml)出现500错误
- 在Struts下中英文转化
- 请教几个Spring的问题
- 刚签了公司,有几个问题,关于J2EE的,谢谢各位了
- 有关 J2EE 的两个小问题
- hibernate自带的分页问题
- Error creating bean with name 'entityManagerFactoryBean'
1、JVM调用b.say函数的同时锁定b实例;
2、say函数中调用a.last();
3、JVM调用调用a.last函数的同时锁定a实例;
4、执行结束。run执行了:a.say(b);
1、JVM调用a.say函数的同时锁定a实例;
2、say函数中调用b.last();
3、JVM调用调用b.last函数的同时锁定b实例;
4、执行结束。那么由于是并发执行,如果目前的状态是:main执行了它第(1)步的同时,run也刚好执行了它的第(1)步,那么接下来似乎谁都没机会去锁定对方了。也就是main持有了b的锁,并请求a的锁;而run持有了a的锁,并请求b的锁。这就是死锁,so ga
B b = new B();
这是你new的两个对象,而你启动线程调用的方法分别为a.say(b);和b.say(a);
而根据你的上面的方法可以看出每个方法都是有锁的。
当a.say里面还没有执行b.last();的时候线程休息了,现在b.say开始执行,
这个时候a和b对象都是分别获得了锁的,现在a.say方法里面的b.last是永远都无法执行的,因为他获取不到锁了,同样,b.say方法里面的a.last也不会去执行了,他们都需要对方的对象,而对方都把自己的对象锁定了的,这样就造成了死锁
2 如果类A和类B中随便加一个无关的非synchronized 方法,死锁就不存在了,何解?
方法上的synchronized是锁整个对象的,不信另外做个实验就知道了:
1、取消所有test方法的synchronize,那么你的程序就不会死锁了;做完这步可以先测试下;
2、给A增加下面这个方法:
synchronized void nothing() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
3、在构造函数的第一句话写:a.nothing();
关于问题2:
能结束只是运气好而已吧,只有当main或run有某个提前执行到了3,程序才能顺利结束。
反正我本机运行过是基本每次都死锁的,即便随意增加几十个非synchronized方法。
在执行到最后的时候,如: A 在等待 ,B也在等待, C得到锁后 Notify A B 其他线程,C wait 失去锁。
A B (无先后顺序)得到锁,执行结束。 其中没有线程唤醒C。故C线程无法结束。