线程死锁情况和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 ...
随机推荐
- 2015GitWebRTC编译实录16
新问题,看应该是视频编解码那里出问题了.找找看.WebRtc VoiceEngine codecs:ISAC/16000/1 (103)ISAC/32000/1 (104)Unexpected cod ...
- uva 10375
/* 选择与除法_________________________________________________________________________________ #include & ...
- RelativeLayout.LayoutParams.addRule()方法
1.应用场景 在使用RelativeLayout布局的时候,通常在载入布局之前在相关的XML文件中进行静态设置即可.但是,在有些情况下,我们需要动态的设置布局 的属性,在不同条件下设置不同的布局排列方 ...
- OpenMP对于嵌套循环应该添加多少个parallel for 分类: OpenMP C/C++ Linux 2015-04-27 14:48 53人阅读 评论(0) 收藏
一个原则是:应该尽量少的使用parallelfor, 因为parallel for也需要时间开销.即: (1)如果外层循环次数远远小于内层循环次数,内层循环较多时,将parallel for加在内层循 ...
- C#委拖小例子
委托具有以下属性: 委托类似于 C++ 函数指针,但它们是类型安全的. 委托允许将方法作为参数进行传递. 委托可用于定义回调方法. 委托可以链接在一起:例如,可以对一个事件调用多个方法. 方法不必与委 ...
- yII中利用urlManager将URL改写成restful风格 这里主要涉及url显示样式
1.打开config文件夹下面的mian.php 2.修改内容 如把地址http://www.test.com/index.php?r=site/page/sid/1修改为http://www ...
- intelij idea 2016.2注册码
激活码: 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1l ...
- 彻底搞好rem 与js的监控
什么是rem 在我看来,rem就是1rem单位就等于html节点fontsize的像素值.所以改变html节点的fontsize是最为关键的一步.根据手机宽度改变相对大小就可以实现自适应了,就不用什么 ...
- DB2技术点
----定义 DECLARE CC VARCHAR(4000); DECLARE SQLSTR VARCHAR(4000); DECLARE st STATEMENT; DECLARE CUR CUR ...
- angular+bootstrap+MVC 之二,模态窗
本例实现一个bootstrap的模态窗 1.HTML代码 <!doctype html> <!--suppress ALL --> <html ng-app=" ...