详细解析死锁形成的原因

 首先,了解死锁,先简略了解,代码块的锁:synchronized (对象){}   锁住参数对象。         synchronized对象和内容访问单一;

  简略扫过一下,死锁和非死锁代码:

死锁:

class Zhangsan{	// 定义张三类
	public void say(){
		System.out.println("张三对李四说:“你给我画,我就把书给你。”") ;
	}
	public void get(){
		System.out.println("张三得到画了。") ;
	}
}

class Lisi{	// 定义李四类
	public void say(){
		System.out.println("李四对张三说:“你给我书,我就把画给你”") ;
	}
	public void get(){
		System.out.println("李四得到书了。") ;
	}
}

public class ThreadDeadLock implements Runnable{
	private static Zhangsan zs = new Zhangsan() ;		// 实例化static型对象
	private static Lisi ls = new Lisi() ;		// 实例化static型对象
	private boolean flag = false ;	// 声明标志位,判断那个先说话
	public void run(){	// 覆写run()方法
		if(flag){
			synchronized(zs){	// 同步张三
				zs.say() ;
				System.out.println("张三正在等待李四的画...");			
				try{
					Thread.sleep(500) ;
					
					
				}catch(InterruptedException e){
					e.printStackTrace() ;
				}
				
				synchronized(ls){
					zs.get() ;
				}
			}
		}else{
			synchronized(ls){
				ls.say() ;
				System.out.println("李四正在等待张三的书...");
			
				try{
					Thread.sleep(500) ;
				}catch(InterruptedException e){
					e.printStackTrace() ;
				}
				
				synchronized(zs){
					ls.get() ;
				}
			}
		}
	}
	public static void main(String args[]){
		ThreadDeadLock t1 = new ThreadDeadLock() ;		// 控制张三
		ThreadDeadLock t2 = new ThreadDeadLock() ;		// 控制李四
		t1.flag = true ;
		t2.flag = false ;
		Thread thA = new Thread(t1) ;
		Thread thB = new Thread(t2) ;
		thA.start() ;
		thB.start() ;
	}
	
}

非死锁:

class Zhangsan1{	// 定义张三类
	public void say(){
		System.out.println("张三对李四说:“你给我画,我就把书给你。”") ;
	}
	public void get(){
		System.out.println("张三得到画了。") ;
	}
}

class Lisi1{	// 定义李四类
	public void say(){
		System.out.println("李四对张三说:“你给我书,我就把画给你”") ;
	}
	public void get(){
		System.out.println("李四得到书了。") ;
	}
}

public class ThreadDeadUnLock implements Runnable{
	private static Zhangsan1 zs = new Zhangsan1() ;		// 实例化static型对象
	private static Lisi1 ls = new Lisi1() ;		// 实例化static型对象
	private boolean flag = false ;	// 声明标志位,判断那个先说话
	public void run(){	// 覆写run()方法
		if(flag){
			synchronized(zs){	// 同步张三
				zs.say() ;
				System.out.println("张三正在等待李四的画...");			
				try{
					Thread.sleep(500);
					zs.wait();			                         //线程睡眠释放资源	
				}catch(InterruptedException e){
					e.printStackTrace() ;
				}
				
				synchronized(ls){
					zs.get() ;
				}
			}
		}else{
			synchronized(ls){
				ls.say() ;
				System.out.println("李四正在等待张三的书...");
			
				try{
					Thread.sleep(500) ;
				}catch(InterruptedException e){
					e.printStackTrace() ;
				}
				
				synchronized(zs){
					ls.get() ;
					zs.notify();
				}
			}
		}
	}
	public static void main(String args[]){
		ThreadDeadUnLock t1 = new ThreadDeadUnLock() ;		// 控制张三
		ThreadDeadUnLock t2 = new ThreadDeadUnLock() ;		// 控制李四
		t1.flag = true ;
		t2.flag = false ;
		Thread thA = new Thread(t1) ;
		Thread thB = new Thread(t2) ;
		thA.start() ;
		thB.start() ;
	}
	
}

      看完了吗?我相信机智的你一定已经发现了他们那些细小的区别。那么我们来分析一下他们运行的过程,在此要记住一个核心知识:睡眠(sleep)不释放线程资源,wait释放线程资源。

        死锁: 创建俩个线程:  线程一synchronized(zs),执行,后面进入睡眠。  
                       在此期间同步锁依旧存在。
                       线程二synchronized(ls),执行,睡眠
                       线程一醒来,执行内部锁synchronized(ls),ls对象被占用,等待。。。
                       线程二醒来,执行内部锁synchronized(zs),zs对象被占用,等待。。。


        活锁: 创建俩个线程:  线程一synchronized(zs),执行,后面进入睡眠。wait()释放资源  
                       在此期间synchronized(zs)被解锁.
                       线程二synchronized(ls),执行,睡眠
                       线程一未被唤醒
                       线程二醒来,执行内部锁synchronized(zs),zs对象未被占用,执行代码,notify()唤醒线程一。
                       线程一执行代码。

      机智的你一定懂了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长臂人猿

客官们众筹请博主喝杯奶茶吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值