1、死锁
1.1、什么是死锁?
-
比较官方的回答是:两个或多个线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象。若无外力作用,它们都将无法推进下去。(回答时就应该用专业的说法,显得你很专业)实际上就是鹬蚌相争8了。
-
举个梨子👇,(二狗拿到厕纸,想上厕所。而山炮进了厕所,想要厕纸。两人互不相让,最后活活憋死)
-
死锁示例代码
-
package com.finajoy.thread; public class DeadLock { public static void main(String[] args) { Object paper = new Object(); Object toilet = new Object(); ergou ergou = new ergou(paper, toilet); shanpao shanpao = new shanpao(paper, toilet); new Thread(ergou).start(); new Thread(shanpao).start(); } } class ergou implements Runnable{ private Object paper; private Object toilet; public ergou(Object paper, Object toilet) { this.paper = paper; this.toilet = toilet; } @Override public void run() { synchronized (paper){ System.out.println("二狗已经拿到了纸"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (toilet){ System.out.println("二狗又进了厕所"); System.out.println("二狗牛逼!"); } } } } class shanpao implements Runnable{ private Object paper; private Object toilet; public shanpao(Object paper, Object toilet) { this.paper = paper; this.toilet = toilet; } @Override public void run() { synchronized (toilet){ System.out.println("山炮已经进了厕所"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (paper){ System.out.println("山炮又拿到了纸"); System.out.println("山炮牛逼!"); } } } }
-
运行结果
1.2、怎么解决死锁?
- 规定资源的使用顺序,例如:规定必须先拿到厕纸才能上厕所。
1.3、有死锁是不是就有活锁
-
互相礼让就会形成活锁
-
package com.finajoy.thread; /** * 活锁的案例 */ public class LiveLock { public static void main(String[] args) { Toilet toilet = new Toilet(); //二狗带山炮上厕所 new Thread(()->{ toilet.setUsableName("二狗"); toilet.goToilet("二狗","山炮"); }).start(); //山炮带二狗上厕所 new Thread(()->{ toilet.setUsableName("山炮"); toilet.goToilet("山炮","二狗"); }).start(); } } class Toilet{ //代表当前可以上厕所的人 private String usableName; public void setUsableName(String usableName){ this.usableName = usableName; } //表示他是否需要上厕所 private boolean isNeed = true; /** * 上厕所的方法 * @param thisName 准备上厕所的人 * @param otherName 另外一个要上厕所的人 */ public synchronized void goToilet(String thisName,String otherName){ //判断是否需要上厕所 while(isNeed){ while(!usableName.equals(thisName)){ //如果准备上厕所的人和允许上厕所的人名字不一致,则等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //先礼让 //判断另外一个人是否需要上厕所(我这里认为只要otherName不为空就需要上厕所) if(otherName!=null){ //将允许上厕所的人修改为otherName this.usableName = otherName; System.out.println(thisName+" 对 " +otherName+" 说您先请!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } this.notifyAll(); }else{ System.out.println(thisName+"愉快地上完了厕所"); isNeed =false; } } } }
-
运行结果: