线程死锁情况和while在线程的作用
public class printDemo04 {
public static void main(String[] args) {
Resource01 resource01 = new Resource01();
Producer producer = new Producer(resource01);
Producers producers = new Producers(resource01);
Thread thread0 = new Thread(producer);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(producers);
Thread thread3 = new Thread(producers);
thread0.start();
thread1.start();
thread2.start();
thread3.start();
}
}
class Resource01{
private String name;
private int sex = 1;
private boolean flag = false;
public synchronized void setSth(String name){
while(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+sex;
sex++;
System.out.println(Thread.currentThread().getName()+"----"+"生产者..."+this.name);
flag = true;
this.notifyAll();
} public synchronized void getSth(){
while(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"--"+"消费者..."+name);
flag = false;
this.notifyAll();
}
}
class Producer implements Runnable{
Resource01 resource01;
public Producer(Resource01 resource01) {
this.resource01 = resource01;
}
int i = 1;
@Override
public void run() {
while(true){
if(i==1){
resource01.setSth("烤鸭");
}
i = (i+1)%2;
}
}
}
class Producers implements Runnable{
Resource01 resource01;
public Producers(Resource01 resource01) {
this.resource01 = resource01;
} @Override
public void run() {
while(true){
resource01.getSth();
}
}
}
死锁发生的情况:上述代码中,把标色的this.notifyAll();改为this.notify();就会发生线程的死锁,为什么呢?应为代码中总共有4个线程,生产者1和生产者2,消费者1和消费者2。理想状态是生产者1和生产者2执行生产操作,消费者1和消费者2执行消费操作,生产一个,消费一个。现在线程进入首先执行生产操作,打个比方生产1生产了烤鸭1,然后flag等于true,如果接下来执行的生产操作的话,这个生产线程就会被等待,这时候执行的生产者2,就会被等待,接下来执行消费者2线程消费者2线程执行完以后flag为false,这时候有要选择一个线程执行,因为生产者2在线程池中被等待,所以现在只能执行生产者1、消费者1和消费者2,假设这时候执行生产者1又生产了烤鸭2,然后又在前面三个线程中选择了生产者1,这时候flag为true,生产者1又进入了线程池进行了等待。然后线程只有2个可以执行消费者1和消费者2,这时候消费完以后,flag为false,接下来只能执行消费线程,但是没法生产flag就只能为false,所以这时候消费者1和消费者2就都会被等待,到此为止,4个线程都被等待,于是就发生了死锁。使用notifyAll()就不会发生死锁了。
while在这的作用是判断当前执行的线程是否应该被执行,就像代码中所表示的执行完生产只能消费。
线程死锁情况和while在线程的作用的更多相关文章
- .NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长
一个 asp.net core 站点,之前运行在Linux 服务器上,运行一段时间后有时站点会挂掉,在日志中记录很多“EMFILE too many open files”的错误: Microsoft ...
- 并发编程-线程-死锁现象-GIL全局锁-线程池
一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这 ...
- 尝试解决在构造函数中同步调用Dns.GetHostAddressesAsync()引起的线程死锁
(最终采用的是方法4) 问题详情见:.NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长 看看在 Linux 与 Windows 上发生线程死锁的后果. Linux: Microsoft ...
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...
- 55行代码实现Java线程死锁
死锁是Java多线程的重要概念之一,也经常出现在各大公司的笔试面试之中.那么如何创造出一个简单的死锁情况?请看代码: class Test implements Runnable { boolean ...
- 对象及变量的并发访问(同步方法、同步代码块、对class进行加锁、线程死锁)&内部类的基本用法
主要学习多线程的并发访问,也就是使得线程安全. 同步的单词为synchronized,异步的单词为asynchronized 同步主要就是通过锁的方式实现,一种就是隐式锁,另一种是显示锁Lock,本节 ...
- java命令分析线程死锁以及内存泄漏
一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...
- Python并发编程-进程 线程 同步锁 线程死锁和递归锁
进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...
- Atitit.线程 死锁 跑飞 的检测与自动解除 与手动解除死锁 java c# .net php javascript.
Atitit.线程 死锁 跑飞 的检测与自动解除 与手动解除死锁 java c# .net php javascript. 1. 现象::主程序卡住无反应,多行任务不往下执行 1 2. 原因::使用j ...
随机推荐
- s查找父节点
查找所有的父节点,包括本身,不包括就<>id with tbs as(select * from TB_HomeBase where ID=223 union all select a.* ...
- 跨域之-jquery操作
在JQ进行跨域的操作,用的是jsonp的方式,创建script标签,除了跨域的行为外,本地的操作方式都是xmlHttpRequest.
- MongoDB学习笔记二:创建、更新及删除文档
插入并保存文档 对目标集使用insert方法插入一个文档: > db.foo.insert({"bar" : "baz"}) 这个操作会给文档增加一个&q ...
- Joint Deep Learning for Pedestrian Detection笔记
1.结构图 Introduction Feature extraction, deformation handling, occlusion handling, and classification ...
- python xlwt,xlutils 在excel里面如何插入一行数据
就是把插入行之后值重新输出来. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import xl ...
- Zookeeper全解析——Paxos作为灵魂(转)
原计划在介绍完ZK Client之后就着手ZK Server的介绍,但是发现ZK Server所包含的内容实在太多,并不是简简单单一篇Blog就能搞定的.于是决定从基础搞起比较好. 那么ZK Serv ...
- 显示hello
The modern user interface is constructed from visual objects of various sorts. Depending on the oper ...
- 查询数组里有多少个数在[L,R]范围中(二分)
使用两次二分即可得到这个值 比如现在有一个vector<int> vec,里面存放的是有序数列. 我们现在希望找出范围在[L,R]之间的数有多少个. 则有cnt = upper_bound ...
- Chap5: question: 29 - 31
29. 数组中出现次数超过一半的数字. 方法a. 排序取中 O(nlogn). 方法b. partition 函数分割找中位数 >=O(n). 方法c. 设计数变量,扫描一遍 ...
- simulate windows touch input
更多信息请参考页面http://social.technet.microsoft.com/wiki/contents/articles/6460.simulating-touch-input-in-w ...