楼上比喻不错,再打个比方:火车上上厕所,一个人进去后,后面的人就要排队等,厕所人出来后,门就开了,下一个人就可以进人.如果所有人都一涌而上,都上不成厕所,这就成了死锁,都挤在门口出不来,进不去.
死锁实例:
- class Ticket implements Runnable {
- boolean flag = true;
- Ticket(boolean flag) {
- this.flag = flag;
- }
- /*
- * 分析:
- * 假设a先线程进入了if(),打开了locka锁,输出了...if....a
- * 这时b也进入了else,打开了lockb锁.输出了...if....b
- * 这时a想打开lockb锁,可是else中b持有着,所以a还打不开,就在这里等着b走完else将lockb锁释放
- * 这时b需要打开locka锁,走出else才能释放lockb锁,但是a在if中持有着locka锁,b也打不开,也在这等待着a走完if将locka锁释放
- * 最终都停在这里出不去,这就是死锁
- * 如何解决:
- * 首先找到问题的所在,让他们共用的锁在释放后,才允许下一个线程持有这个锁,这个还是主要分析具体的情况,这代码就是一个死锁的代码示例
- * */
- public void run() {
- if (flag) {
- synchronized (Mylock.locka) {
- System.out.println(Thread.currentThread().getName()
- + "...if....a");
- synchronized (Mylock.lockb) {
- System.out.println(Thread.currentThread().getName()
- + "...if....b");
- }
- }
- } else {
- synchronized (Mylock.lockb) {
- System.out.println(Thread.currentThread().getName()
- + "...else....a");
- synchronized (Mylock.locka) {
- System.out.println(Thread.currentThread().getName()
- + "...else....b");
- }
- }
- }
- }
- }
- class Mylock {
- public static final Object locka = new Object(); //locka用于线程a的锁
- public static final Object lockb = new Object(); //lockb用于线程b的锁
- }
- public class Test1 {
- public static void main(String[] args) throws InterruptedException {
- Ticket a = new Ticket(true); //让a走if语句
- Ticket b = new Ticket(false);//让b走else语句
- Thread t1 = new Thread(a);
- Thread t2 = new Thread(b);
- t1.start(); //开启线程
- t2.start();
- }
- }
复制代码 |