死锁实现
public class DeathLockTest { static Integer b = 100; static Integer a = 0; public static void main(String[] args) { new Thread(() -> { synchronized (a){ System.out.println(Thread.currentThread().getName() + ": i locked a"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (b){ System.out.println(Thread.currentThread().getName() + ": i locked b"); } } },"thread-a").start(); new Thread(() -> { synchronized (b){ System.out.println(Thread.currentThread().getName() + ": i locked b"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (a){ System.out.println(Thread.currentThread().getName() + ": i locked a"); } } },"thread-b").start(); }}

死锁结果
这里简单的用了两个线程去分别获取到a的锁和b的锁,然后再获取另外一个锁的时候,就发现互相等待,互相不会释放资源,导致死锁的发生。死锁在我们的项目中会导致很严重的后果,有多严重,碰到的人知道。
定义
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。[百度百科]
如何避免
1:获取锁的顺序问题
如果我们在获取两个资源的时候,获取的顺序相同,都先获取到a的锁,然后再获取到b的锁,则在上述例子中避免了死锁。
2:避免同时持有两个资源的锁
假设上面的例子中,thread-a获取到a的锁以后,对a的操作进行完成以后再获取b的锁,那么,就可以解开这个死锁,thread-b同理。
3:使用java.util.concurrent包中的相关方法改造
对上面的代码进行改造
public class DeathLockTest2 { static Integer a = 0; static Integer b = 100; static Lock lock1 = new ReentrantLock(); static Lock lock2 = new ReentrantLock(); public static void main(String[] args) { new Thread(()->{ try{ if(lock1.tryLock()){ System.out.println(Thread.currentThread().getName() + ": lock1 was locked"); a++; try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if(lock2.tryLock()){ System.out.println(Thread.currentThread().getName()+ " lock2 was locked"); b--; } System.out.println(Thread.currentThread().getName()+ "--> ++a :" + a + " , --b:" + b); } }finally { lock1.unlock(); lock2.unlock(); } },"thread-a").start(); new Thread(()->{ try { if(lock2.tryLock()){ System.out.println(Thread.currentThread().getName()+ " lock2 was locked"); b--; try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if(lock1.tryLock()){ System.out.println(Thread.currentThread().getName() + ": lock1 was locked"); a++; } } System.out.println(Thread.currentThread().getName()+ "--> ++a :" + a + " , --b:" + b); }finally { lock2.unlock(); lock1.unlock(); } },"thread-b").start(); //定时器计时 new Timer().schedule(new TimerTask(){ @Override public void run() { System.out.println(String.valueOf(Calendar.getInstance().get(Calendar.SECOND))); } }, 1, 1000); }}
使用java.util.concurrent.locks.Lock.tryLock()
方法,结果如下:

解锁
程序在等待了5s左右的时候,线程自动结束运行了,使用这种方式则不会使我们的线程出现完全死锁,程序无法进行的状态,在等待一定时间后,线程无法获取到锁,则自动放弃获取锁。
结束语:可能还有更好的解决办法,欢迎大家留言指正探讨,谢谢!
文章转载于:https://www.jianshu.com/p/07a43e0fba26
原著是一个有趣的人,若有侵权,请通知删除
还没有人抢沙发呢~