36 多线程(八)——线程造成死锁
一线程持有a资源,需要获取b资源才释放a资源。
二线程持有b资源,需要获取a资源才释放b资源。
造成死锁。
下面举个例子:
两个女人化妆,需要镜子和口红,两个人一个先拿镜子,再拿口红,另一个先拿口红,再拿镜子
/** * @author TEDU * 死锁出现的情况多是锁套锁。 */ public class DeadLock { public static void main(String[] args) { MakeUp m1 = new MakeUp("小红",1); MakeUp m2 = new MakeUp("小丽",2); m1.start(); m2.start(); } } //镜子 class Mirror{ } //口红 class Lipstick{ } //化妆 class MakeUp extends Thread{ //这里是静态修饰,保证她们拿到的是同一个镜子和口红 private static Mirror mirror = new Mirror(); private static Lipstick lipstick = new Lipstick(); private String name; private int choice; public MakeUp(String name,int choice) { this.name = name; this.choice = choice; } @Override public void run() { // TODO Auto-generated method stub super.run(); makeUp(choice); } public void makeUp(int choice) { if(choice == 1) { synchronized (mirror){ //先拿了镜子 System.out.println(name+"拿了镜子"); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (lipstick) {//写在锁中的锁:拿口红 //再拿了镜子 System.out.println(name+"拿了口红"); } } }else { synchronized (lipstick){ //先拿了口红 System.out.println(name+"拿了口红"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (mirror) {//写在锁中的锁:拿镜子 //再拿了镜子 System.out.println(name+"拿了镜子"); } } } } }
这个程序就会造成死锁。
本例解决方法:放下已有资源(解锁),再获取另一个资源。
也就是将锁套锁解除,将写在同步块里的同步块拿出来并列即可。
if(choice == 1) { synchronized (mirror){ //先拿了镜子 System.out.println(name+"拿了镜子"); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } synchronized (lipstick) {//锁单独写出来:拿口红 //再拿了镜子 System.out.println(name+"拿了口红"); } }