java初学者 加入小组

293个成员 64个话题 创建时间:2015-02-03

关于“死锁”,这样理解对吗?求解答。

发表于2016-07-18 2234次查看

关于“死锁”,《JAVA开发实战经典》一书上有个例子,我小改了一下,感觉这样容易理解些,这样的思路是否正确?运行结果是一样的。

laughlaughlaugh

class ZhangSan
{
	public void say(){
		System.out.println("张三对李四说:“你给我画,我就把书给你。”");
	}
	public void get(){
		System.out.println("张三得到画了。");
	}
	public void give(){
		System.out.println("张三把书给李四了。");
	}
};
class LiSi
{
	public void say(){
		System.out.println("李四对张三说:“你给我书,我就把画给你。”");
	}
	public void get(){
		System.out.println("李四得到书了。");
	}
	public void give(){
		System.out.println("李四把画给张三了。");
	}
};
class Exchange implements Runnable
{
	private ZhangSan zs;
	private LiSi ls;
	private boolean flag;
	public Exchange(ZhangSan zs,LiSi ls,boolean flag){
		this.zs = zs;
		this.ls = ls;
		this.flag = flag;
	}
	public void run(){
		if (this.flag)
		{
			synchronized(zs){
				zs.say();
				synchronized(ls){
					try{
						Thread.sleep(500);
					}catch(Exception e){
						e.printStackTrace();
					}
					ls.give();
				}
				zs.get();
				try{
					Thread.sleep(500);
				}catch(Exception e){
					e.printStackTrace();
				}
				zs.give();
			}
		}else{
			synchronized(ls){
				ls.say();
				synchronized(zs){
					try{
						Thread.sleep(500);
					}catch(Exception e){
						e.printStackTrace();
					}
					zs.give();
				}
				ls.get();
				try{
					Thread.sleep(500);
				}catch(Exception e){
					e.printStackTrace();
				}
				ls.give();
			}
		}
	}
};
public class ThreadDeadLock
{
	public static void main(String args[]){
		ZhangSan zs = new ZhangSan();
		LiSi ls = new LiSi();
		Exchange e1 = new Exchange(zs,ls,true);
		Exchange e2 = new Exchange(zs,ls,false);
		new Thread(e1).start();
		new Thread(e2).start();
	}
};

 

1回复
  • 2楼 Jacksonville 2016-07-22

    你这样写虽然运行结果是对的,但是你错误的理解加Thread.sleep(500)的意义了,你的意思可能是要等5毫秒才能把书给我

     

    而且这个sleep并没有起任何作用,为什么运行结果会一样,因为代码没有运行到这个同步快里面来,书中加sleep只是模拟让死锁更能重现出来,不加的话就有可能张三刚开始对李四说你给我画,我把书给你,张三就已经得到画了,而这时李四才刚开始说

    你要明白synchronized(obj){}的作用,就是必须等这个obj在其他的线程的同步操作执行完,才能执行里面同步块的操作,而书中为什么会有死锁,是因为当flag为false时,执行到synchronized(zs){}时,而zs被flag为true时同步着还没执行完,同样的flag为true时,执行到synchronized(ls){}时,而ls被flag为false时同步着还没执行完

     

发表回复
你还没有登录,请先 登录或 注册!