package com.thread.deadlock; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 死锁的出现分2中情况: * 1.锁顺序死锁 * 2.资源死锁 * 资源死锁的典型例子是:线程饥饿死锁和数据库连接池的饥饿死锁 * * 本例演示的是锁顺序死锁 * 当一个线程永远占用一个锁,而其他线程尝试去获得这个锁,那么它们将永远被阻塞。 * 当线程A占用锁L时,想要获得锁M,但是同时,线程B持有锁M,并尝试获得L,两个线程将永远等待下去。 * 这种情况是死锁最简单的形式(或称致命的拥抱)。 * 发生在多个线程因为环路的锁依赖关系而永远等待的情况下。 * * * 怎么避免出现锁顺序死锁? * 如果所有线程以通用的固定秩序获得锁,程序就不会出现锁顺序死锁的问题了。 * * @author hadoop * */ public class LeftRightDeadlock { private final Object left = new Object(); private final Object right = new Object(); public void leftToRight(){ synchronized(left){ synchronized(right){ try { Thread.currentThread().sleep(20);//延迟执行时间,提高死锁概率 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "执行从左到右顺序的操作"); } } } public void RightToLeft(){ synchronized(right){ synchronized(left){ try { Thread.currentThread().sleep(30); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"执行从右到左顺序的操作"); } } } public static void main(String[] args) { ExecutorService mExecutor = Executors.newCachedThreadPool(); final LeftRightDeadlock lrlock = new LeftRightDeadlock(); for (int i = 0; i < 1000; i++) { mExecutor.execute(new Runnable() { @Override public void run() { lrlock.RightToLeft(); } }); } for (int i = 0; i < 1000; i++) { mExecutor.execute(new Runnable() { @Override public void run() { lrlock.leftToRight(); } }); } } }