多线程死锁:同步中嵌套同步,导致锁无法释放。
死锁解决办法:不要在同步中嵌套同步
public class Demo06DeadLock { public static void main(String[] args) { //创建线程任务对象 Ticket ticket = new Ticket(); //创建三个窗口对象 Thread t1 = new Thread(ticket, "窗口1"); Thread t2 = new Thread(ticket, "窗口2"); Thread t3 = new Thread(ticket, "窗口3"); //卖票 t1.start(); t2.start(); t3.start(); } static class Ticket implements Runnable { Object obj = new Object(); private int ticket = 100; public void run() { String name = Thread.currentThread().getName(); while (true) { if ("窗口1".equals(name)) { synchronized (obj) { sell(name); } } else { sell(name); } if (ticket <= 0) { break; } } } private synchronized void sell(String name) { synchronized (obj) { if (ticket > 0) { System.out.println(name + "卖票:" + ticket); ticket--; } } } } }
同步方法的同步锁是谁:
1、对于非static方法,同步锁就是this。
2、对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。
分析:
同步代码块的锁是obj,同步方法的锁是this,窗口1先获取obj,再获取this,再获取obj,即窗口1要三次获取锁。窗口2和窗口3先获取this,再获取obj,当窗口1获取了obj后等待this,而窗口2获取了this而等待obj,此时出现了死锁。
结果为:
买到第14张票时,程序为继续卖票也未停止执行。
再次运行,会出现如下结果:只卖1张票,程序就不再继续卖票且未结束。
网络上关于死锁的内容:
所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。如下图所示: