java中多线程中测试某个条件的变化用 if 还是用 while?
最近在研究wait和notify方法,发现有个地方要注意,但是网上又说得不是很明白的地方,就是经典的生产者和消费模式,使用wait和notify实现,判断list是否为空的这个为什么要用while而不能使用if呢?其实是因为当线程wait之后,又被唤醒的时候,是从wait后面开始执行,而不是又从头开始执行的,所以如果用if的话,被唤醒之后就不会在判断if中的条件,而是继续往下执行了,如果list只是添加了一个数据,而存在两个消费者被唤醒的话,就会出现溢出的问题了,因为不会在判断size是否==0就直接执行remove了。但是如果使用while的话,从wait下面继续执行,还会返回执行while的条件判断,size>0了才会执行remove操作,所以这个必须使用while,而不能使用if来作为判断。
public class Add {
private String lock;
public Add(String lock) {
super();
this.lock = lock;
}
public void add() {
synchronized (lock) {
ValueObject.list.add("anyString");
lock.notifyAll();
}
}
}
public class ThreadAdd extends Thread {
private Add p;
public ThreadAdd(Add p) {
super();
this.p = p;
}
@Override
public void run() {
p.add();
}
}
public class Subtract {
private String lock;
public Subtract(String lock) {
super();
this.lock = lock;
}
public boolean check() {
System.out.println("check");
return true;
}
public void subtract() {
try {
synchronized (lock) {
if(check() && ValueObject.list.size() == 0) {//将这里的if改成while即可保证不出现越界异常!!!!
System.out.println("wait begin ThreadName="
+ Thread.currentThread().getName());
lock.wait();
System.out.println("wait end ThreadName="
+ Thread.currentThread().getName());
}
ValueObject.list.remove(0);
System.out.println("list size=" + ValueObject.list.size());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadSubtract extends Thread {
private Subtract r;
public ThreadSubtract(Subtract r) {
super();
this.r = r;
}
@Override
public void run() {
r.subtract();
}
}
public class ValueObject {
public static List list = new ArrayList();
}
public class Run {
public static void main(String[] args) throws InterruptedException {
String lock = new String("");
Add add = new Add(lock);
Subtract subtract = new Subtract(lock);
ThreadSubtract subtract1Thread = new ThreadSubtract(subtract);
subtract1Thread.setName("subtract1Thread");
subtract1Thread.start();
ThreadSubtract subtract2Thread = new ThreadSubtract(subtract);
subtract2Thread.setName("subtract2Thread");
subtract2Thread.start();
Thread.sleep(1000);
ThreadAdd addThread = new ThreadAdd(add);
addThread.setName("addThread");
addThread.start();
}
}
java中多线程中测试某个条件的变化用 if 还是用 while?的更多相关文章
- Java接口多线程并发测试 (一)
本文为作者原创,禁止转载,违者必究法律责任!!! 本文为作者原创,禁止转载,违者必究法律责任!!! Java接口多线程并发测试 一,首先写一个接口post 请求代码: import org.apach ...
- C#中多线程中变量研究
今天在知乎上看到一个问题[为什么在同一进程中创建不同线程,但线程各自的变量无法在线程间互相访问?].在多线程中,每个线程都是独立运行的,不同的线程有可能是同一段代码,但不会是同一作用域,所以不会共享. ...
- 在 Java 的多线程中,如何去判断给定的一个类是否是线程安全的(另外:synchronized 同步是否就一定能保证该类是线程安全的。)
同步代码块和同步方法的区别:同步代码块可以传入任意对象,同步方法中 如果多个线程检查的都是一个新的对象,不同的同步锁对不同的线程不具有排他性,不能实现线程同步的效果,这时候线程同步就失效了. 两者的区 ...
- java中多线程中Runnable接口和Thread类介绍
java中的线程时通过调用操作系统底层的线程来实现线程的功能的. 先看如下代码,并写出输出结果. // 请问输出结果是什么? public static void main(String[] args ...
- Java:多线程中的volatile
一.为什么使用volatile 首先,通过一段简单的代码来理解为什么要使用volatile: public class RunThread extends Thread{ private boolea ...
- Java之多线程开发时多条件Condition接口的使用
转:http://blog.csdn.net/a352193394/article/details/39454157 我们在多线程开发中,可能会出现这种情况.就是一个线程需要另外一个线程满足某某条件才 ...
- Java接口多线程并发测试 (二)
原文地址http://www.cnblogs.com/yezhenhan/archive/2012/01/09/2317636.html 这是一篇很不错的文章,感谢原博主的分享! JAVA多线程实现和 ...
- C#中多线程的并行处理
System.Threading.Tasks,在该命名空间下Task是主类,表示一个类的异步的并发的操作,创建并行代码的时候不一定要直接使用Task类,在某些情况下可以直接使用Parallel静态类( ...
- Java的多线程实现生产/消费模式
Java的多线程实现生产/消费模式 在Java的多线程中,我们经常使用某个Java对象的wait(),notify()以及notifyAll() 方法实现多线程的通讯,今天就使用Java的多线程实现生 ...
随机推荐
- C# Redis辅助类封装与简单聊天室的实现思路说明
虽然redis api的功能比较齐全,但个人觉得为了更好的方便学习和使用,还是很有必有做一个类似DBHelper的帮助类 辅助类主要功能(代码会在最后放出来) 1. 事件监听: 重新配置广播时(主从同 ...
- Windows上编译zlib
把zlib 1.2.8解压到zlib/zlib-1.2.8 在deflate.c文件中把deflate_copyright改成一个static变量. 在zlib目录底下创建并用Visual Studi ...
- eclipse 中文或法文等语言注释错误解决办法 Some characters cannot be mapped using "GBK" character encoding
这个问题会造成 无法修改包名.解决办法: Window->Preferences->Content Types->Text->Java Source File Default ...
- 【OCP-12c】CUUG最新考试原题整理及答案(071-9)
9.(5-5) choose the best answerView the Exhibit and examine the structure of the SALES and STORES tab ...
- “全栈2019”Java第七十九章:类中可以嵌套接口吗?
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- [Swift]多维数组的表示和存储:N维数组映射到一维数组(一一对应)!
数组:有序的元素序列. 若将有限个类型相同的变量的集合命名,那么这个名称为数组名.组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量.用于区分数组的各个元素的数字编号称为下标.数组 ...
- Linux 下 SSH 远程超时解决方案
Linux 下 SSH 远程超时解决方案 今天突然看到一个问题说是如何解决SSH远程超时的问题. 找了一点资料.用于解决这个需求~ 第一种:OpenSSH 配置文件设置 位于112行的 "C ...
- Python实现——二层BP神经网络
2019/4/23更新 下文中的正确率极高是建立在仅有50组训练数据的基础上的,十分不可靠.建议使用提供的另一个生成训练集的generate_all函数,能产生所有可能结果,更加可靠. 2019/4/ ...
- P2057 [SHOI2007]善意的投票 最小割
$ \color{#0066ff}{ 题目描述 }$ 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照 ...
- 使用Mondrian Virtual OLAP Cube 实现星座模型并在saiku展现分析
1.什么是星座模型? 2.哪些地方可以用到星座模型? 3.Mondrian怎么构建星座模型,构建过程又涉及到哪些理论概念. 答1:这里描述了维度模型常用的 星型.雪花.星座模型,简而言之就是多事实表模 ...