关于死锁,估计很多程序员都碰到过,并且有时候这种情况出现之后的问题也不是非常好排查,下面整理的就是自己对死锁的认识,以及通过一个简单的例子来来接死锁的发生,自己是做python开发的,但是对于死锁的理解一直是一种模糊的概念,也是想过这次的整理更加清晰的认识这个概念。

用来理解的例子是一个简单的生产者和消费者模型,这里是有一个生产者,有两个消费者,并且注意代码中使用notify方法的代码行

packagestudy_java.ex11;importjava.util.LinkedList;importjava.util.List;public classPCDemo1 {public static voidmain(String[] args){

Pool pool= newPool();

Producter p1= newProducter(pool);

p1.setName("p1");

Consumer c1= newConsumer(pool);

Consumer c2= newConsumer(pool);

c1.setName("c1");

c2.setName("c2");

p1.start();

c1.start();

c2.start();

}

}classPool{private List list = new LinkedList();private int Max = 1;public void addLast(intn){

String name=Thread.currentThread().getName();synchronized (this){while (list.size() >=Max){try{

System.out.println(name+".wait()");this.wait();

}catch(Exception e){

e.printStackTrace();

}

}

System.out.println(name+ "+" +n);

list.add(newInteger(n));

System.out.println(name+ ".notify()");this.notify(); //注意这里是调用的是notify方法

}

}public intremove(){

String name=Thread.currentThread().getName();synchronized (this){while (list.size() == 0){try{

System.out.println(name+ ".wait()");this.wait();

}catch(Exception e){

e.printStackTrace();

}

}

System.out.println(name+ "-" + 0);int no = list.remove(0);

System.out.println(name+ ".notify()");this.notify(); //注意这里是调用的是notify方法

returnno;

}

}

}//生产者

class Producter extendsThread{privatePool pool;static int i = 1;publicProducter(Pool pool){this.pool =pool;

}public voidrun(){while (true){

pool.addLast(i++);

System.out.println("生产者生产了"+i+"号");

}

}

}//消费者

class Consumer extendsThread{privatePool pool;publicConsumer(Pool pool){this.pool =pool;

}public voidrun(){while (true){int no =pool.remove();

System.out.println("消费者消费了"+no+"号");

}

}

}

这段代码的运行效果是日志,在最后程序卡主不动了:

c1.wait()

p1+1p1.notify()

c1-0c1.notify()

消费者消费了1号

c1.wait()

生产者生产了2号

p1+2p1.notify()

c1-0c1.notify()

消费者消费了2号

c1.wait()

生产者生产了3号

p1+3p1.notify()

c1-0c1.notify()

消费者消费了3号

c1.wait()

生产者生产了4号

p1+4p1.notify()

c1-0c1.notify()

消费者消费了4号

c1.wait()

生产者生产了5号

p1+5p1.notify()

c1-0c1.notify()

消费者消费了5号

c1.wait()

生产者生产了6号

p1+6p1.notify()

生产者生产了7号

c1-0c1.notify()

消费者消费了6号

c1.wait()

p1+7p1.notify()

生产者生产了8号

p1.wait()

c2-0c2.notify()

消费者消费了7号

c2.wait()

c1.wait()

p1+8p1.notify()

生产者生产了9号

p1.wait()

c2-0c2.notify()

消费者消费了8号

c2.wait()

c1.wait()

对上面的出现卡主的情况进行分析,理解为啥会卡主:

从这次的执行效果可以看出第一次是c1抢到了执行权,但是这个时候pool是空

所以c1没有可以消费的对象,被放入到了等待队列

接着p1抢到了执行权,生产了1个,然后p1.notify(),这个时候等待队列里只有c1,所以c1被唤醒,c1消费了1个,然后c1.notify(), 这个时候等待队列也没有等待的,这个时候有被c1抢到了执行权,但是pool里没有可以消费的内容,所以c1.wait() 进入到等待队列

这个时候p1抢到执行权,生产了1个,然后p1.notify(),这个时候等待队列里只有c1,所以c1被唤醒,c1也抢到了执行权,消费了1个,然后c1.notify()

同样这个时候等待队列里没有等待的,c1这次又抢到了执行权,但pool里没有可以消费的内容,所以c1.wait(),进入到等待队列

p1 又抢到了执行权,生产1个,然后p1.notify(),这个时候等待队列里只有c1,所以c1被唤醒,c1也抢到了执行权,消费了1个,然后c1.notify()

同样这个时候等待队列里没有等待的,c1这次又抢到了执行权,但pool里没有可以消费的内容,所以c1.wait(),进入到等待队列

.......这种情况重复了几次

但是运行到下面这段的时候问题出现了:

p1+7p1.notify()

生产者生产了8号

p1.wait()

c2-0c2.notify()

消费者消费了7号

c2.wait()

c1.wait()

p1+8p1.notify()

生产者生产了9号

p1.wait()

c2-0c2.notify()

消费者消费了8号

c2.wait()

c1.wait()

继续进行分析,中间重复的部分不做分析了,和前面的过程是一样的

这个时候等待队里里依然是c1 这个时候p1抢到了执行权,生产了1个,p1.notify() 这个时候等待队列里只有c1,所以c1被唤醒,但是c1没有抢过p1,p1自己又抢到了执行权,但是这个时候pool里面已经有内容,所以p1没有生产,p1.wait(),p1进入等待队列

这个时候c2抢到了执行权,c2消费1个,c2.notify() 这个时候等待队里是p1,p1被唤醒,但是这个时候c2抢到了执行权,但是pool没有内容可以消费所以c2.wait() 进入等待队列

接着c1抢到了执行权,同样pool没有可以消费的内容,c1.wait() 进入到等待队列

p1这个时候抢到了执行权,p1生产了1个,接着p1.notify() 这个时候等待队列里有c1和c2,但是只有一个会被唤醒,不管是哪个,结果没抢过p1,p1再次拿到执行权,但是这个时候pool已经有内容,所以p1.wait() p1进入等待队列

从下面是c2执行,可以看出刚才是c2被唤醒了,这个时候c2也拿到了执行权消费了1个。c2.notify() 等待队列里这个时候有c1 和p1 但是这个时候c2 自己抢到了执行权,但是没有可以消费的,c2.wait() c2 进入等待队列

不巧的是刚才抢到执行权的正好是c1,所以c1继续wait,再次进入等待队列

到这个时候p1 c1 c2 都进入等待队列里,都在等待唤醒,也就出现了程勋最后卡住不动的情况

解决的方法有两种:

第一种:

其实解决上面的方法也比较简单,就是把调用notify的地方全部换成notifyAll方法

notify和notifyAll的区别是,当执行notifyAll的时候会唤醒所有等待的线程,从而避免之前的都在等待队列等待的问题

第二种:

就是wait()的时候加上超时参数,不是像之前一直傻等,而是在超过既定的时间之后自己唤醒

java中死锁_关于java中死锁的总结相关推荐

  1. java多线程同步与死锁_浅析Java多线程中的同步和死锁

    Value Engineering 1基于Java的多线程 多线程是实现并发机制的一种有效手段,它允许编程语言在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间相互独立,且与进程一样拥有独立 ...

  2. java jstack 死锁_利用jstack检测死锁DeadLock

    首先,制造一个死锁程序如下: public class testJstack { final static Object obj_1 = new Object(); final static Obje ...

  3. java jstack 死锁_用jstack找死锁

    java死锁主要依靠jstack命令来查找. 检测jstack 先配置好jdk环境变量,打开一个终端命令行,输入jstack回车.如果看到如下的字样,说明jstack是可用的. Usage: jsta ...

  4. java coin介绍_代码示例中的Java 7:Project Coin

    java coin介绍 该博客通过代码示例介绍了一些新的Java 7功能,这些项目在Project Coin一词下进行了概述. Project Coin的目标是向JDK 7添加一组小的语言更改.这些更 ...

  5. java final 类_在Java中,final修饰的类有什么特点

    展开全部 关于Java中的32313133353236313431303231363533e4b893e5b19e31333264663736final(2010-09-09 14:19:48)转载▼ ...

  6. java arraylist 函数_使用Java-8中的函数ArrayList

    问题描述: 我希望能够使用从另一个类传入的函数的ArrayList(其中函数已在其他类中定义).如果在一个类中定义了可能具有不同输入和返回类型的函数列表,我希望能够将其中一些的ArrayList(可能 ...

  7. java logging包_用JDK中提供的java.util.logging.*包创建Logger对象----原创

    由于项目中用到了Applet与Servlet之间(客户端用Applet.Server端用Servlet)的通信,要求: 1:>客户端与服务端必须出Log. 2:>浏览器在加载Applet时 ...

  8. android studio插入数据表中没有_学Java能拿高薪吗 Java中常见排序算法有哪些

    学Java能拿高薪吗?Java中常见排序算法有哪些?作为老牌编程语言,Java拥有广阔的市场占有率,几乎90%以上的大中型互联网应用系统在服务端开发都会首选Java.为了加入到Java这一高薪行业,很 ...

  9. java jar 目录_将Java类路径中的所有jar包括在一个目录中

    有没有一种方法可以将所有的jar文件包含在类路径的目录中? 我正在尝试java -classpath lib / *.jar :. my.package.Program,它无法找到当然在这些罐子里的类 ...

  10. java gradle构建_在Gradle中为JPMS构建Java 6-8库

    java gradle构建 通过提供Java 9 module-info.class了解如何使用Gradle构建支持JPMS( Java平台模块系统 )的Java 6-8库. 介绍 如果您需要JPMS ...

最新文章

  1. 鸟哥的Linux私房菜10.16 vim程序编辑器
  2. Java继承时构造函数的关系
  3. 【数据结构与算法】之面试必考的“二分算法”系统梳理
  4. 41.django中auth用户认证
  5. web测试点和app测试点
  6. android sqlite多条件查询,sqlite 多条件查询
  7. php随浏览器大小变化,如何在将图像显示到浏览器之前使用php重新调整图像大小?...
  8. 基于SQL求集合的交、并、补
  9. word文档怎么删除多余的空白页?
  10. ListView和条目点击事件、条目长按事件
  11. xp win7 绿色chrome
  12. Kali网络渗透测试二——网络嗅探与身份认证
  13. 我的软件推广成功之路 [转]
  14. Beta产品测试报告:那周余嘉熊掌将得队、为了交项目干杯队
  15. Windows server 2012R2或Windows 8.1如何成功离线安装.net 4.7
  16. 笔记:刘未鹏思考的技术与艺术(原“学会思考”)
  17. 做好公司网站建设方案的关键在于这些方面
  18. 回首来路漫漫,矢志不改初心
  19. linux磁盘分区fdisk命令详解及云硬盘挂载实操
  20. 分组密码的设计思想、概述、含义

热门文章

  1. Flink 零基础实战教程:如何计算实时热门商品
  2. 三问(why?what?how?)金融领域的机器学习
  3. 双十一丝般顺滑体验背后:阿里云洛神网络虚拟化系统揭秘
  4. 火山引擎进军云市场,计划未来三年服务十万客户
  5. Kubernetes 也有局限性吗?
  6. 腾讯智慧交通战略重磅升级 打造以人为中心的未来交通
  7. MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划
  8. 国庆出游,这个银行卡大小的充电宝一定要带
  9. Kafka精华问答 | Kafka的主要应用场景有哪些?​
  10. python 下载图片到内存卡_python - 获取图像大小而不将图像加载到内存中