一个死锁的问题求大神解答一下,问题在注释处

张甲 2017-07-28 03:44:48
package tv.lufei.one;
//第二种
public class Test6 implements Runnable{

private A a = new A();
private B b = new B();



public static void main(String[] args) {
new Test6();
}
public Test6() {
// System.out.println();为什么加了这个注释,就不是死锁了呀?
new Thread(this).start();


b.say(a);
}
@Override
public void run() {
// System.out.println("执行了run");
a.say(b);
}
}
class A{
public synchronized void say(B b){
System.out.println("A说:你先放人,我就给钱!");
b.get();
}
public synchronized void get(){
System.out.println("A:救了人,付出了钱!");
}
}
class B{
public synchronized void say(A a){
System.out.println("B说:你先给钱,我就放人!");
a.get();
}
public synchronized void get(){
System.out.println("B:放了人,拿到了钱!");
}
}




不加注释,是死锁,输出
/*B说:你先给钱,我就放人!
A说:你先放人,我就给钱!*/


加了注释,就不是死锁了,输出
/*
B说:你先给钱,我就放人!
A:救了人,付出了钱!
A说:你先放人,我就给钱!
B:放了人,拿到了钱!
*/

求大神们仔细分析一下原因
...全文
147 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
110成成 2017-07-28
  • 打赏
  • 举报
回复
b.say(a); a.say(b); 互锁了,加打印信息,是因为执行打印需要时间,就像编程中经常遇到的debug模式下没有问题 但是release下会遇到问题,道理是一样的,这种情况一般加信号量试试。
张甲 2017-07-28
  • 打赏
  • 举报
回复
引用 4 楼 u014038116 的回复:
你这么写,不管你加没加那个注释,都有可能出现死锁或者不出现死锁,你多运行几次就知道了(我试过的),你要想模拟,最好加个休眠,才可以更好的体现,不然有可能 b.say(a);(或者a.say(b);)一下子就先全部跑完了
你好,请问如果加休眠加在哪里比较好呀?麻烦你复制一下可以吗?我加在了run里面还是这样,十分感谢
张甲 2017-07-28
  • 打赏
  • 举报
回复
你好,请问如果加休眠加在哪里比较好呀?麻烦你复制一下可以吗?我加在了run里面还是这样,十分感谢
xiaovhao 2017-07-28
  • 打赏
  • 举报
回复
你这么写,不管你加没加那个注释,都有可能出现死锁或者不出现死锁,你多运行几次就知道了(我试过的),你要想模拟,最好加个休眠,才可以更好的体现,不然有可能 b.say(a);(或者a.say(b);)一下子就先全部跑完了
soton_dolphin 2017-07-28
  • 打赏
  • 举报
回复
a.say(b) 和 b.say(a) 一起运行,当然死锁。
mmqw 2017-07-28
  • 打赏
  • 举报
回复
出现这个现象,是和System.out.println("执行了run"); 这个输出有关系 new Thread(this).start(); 这个时候线程还是就绪状态 然后执行 b.say(a); 锁定a ,线程进入执行状态 run System.out.println("执行了run"); 这句话给了b.say(a); 执行完的时间,没有锁定b ,最终没有进入死锁 这个和运行的代码比较简单,运行时间比较短有关系,可能也不是必现 A和B你改成,死锁就是必现的了
class A{
	    public synchronized void say(B b){
	    	try
			{
				Thread.sleep(1000);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
	        System.out.println("A说:你先放人,我就给钱!");
	        b.get();
	    }
	    public synchronized void get(){
	        System.out.println("A:救了人,付出了钱!");
	    }
	}
	class B{
	    public synchronized void say(A a){
	    	try
			{
				Thread.sleep(1000);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
	        System.out.println("B说:你先给钱,我就放人!");
	        a.get();
	    }
	    public synchronized void get(){
	        System.out.println("B:放了人,拿到了钱!");
	    }
	}
李德胜1995 2017-07-28
  • 打赏
  • 举报
回复
和注释没关系。。。你多运行几次。。。

51,408

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧