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的多线程实现生 ...
随机推荐
- 按照已有的模板输出<一>(如发票)
按照已有的模板输出<一> 普通的发票基本上都是固定模式,所以我们一般写好固定的模板,把其中需要变动的地方,以特定符号来代替.每次打印发票的时候,只需将其中的特定符号转换成我们需要显示的数据 ...
- 格式化JavaScript代码
javascript代码格式化工具 网上下载的js代码经常遇到代码已被压缩(注释.换行.缩进.空格.TAB等都被删除了),如果拿来学习.研究的话必定看到头晕.有些编辑器的“格 式化代码”功能可以解决这 ...
- 菜鸟的Xamarin.Forms前行之路——windows下VS运行ios模拟器调试
在Xamarin.Forms项目中,运行安卓模拟器是很方便的,但是想要运行IOS模拟器,相对而言是困难一点. 在参考一些资料后,发现很多是与Xamarin.studio有关的方法,尝试了许久没有成功. ...
- dubbo 安装部署
dubbo 安装部署 1 安装zookeeper 2 安装dubbo 1 下载源码 https://github.com/alibaba/dubbo 2 编译 mvn clean packa ...
- nginx location 与 rewrite详解 (转)
点我
- Linux常用运维指令
cd data/apps./=========================================== ps -ef | grep tomcatps -ef | grep desktopX ...
- [Swift]扩展String类:extension String
请参考本博客另一篇技术博文: <[Swift]字符串(String类.NSString类)常用操作> extension String { //获取字符串首字符 var first: St ...
- TensorFlow支持GPU配置问题
目录 Tensorflow-GPU 环境条件 现有硬件 现有软件 硬件要求 软件要求 步骤 0.Visual studio 1.下载安装显卡驱动 2.下载对应版本 CUDA 3.安装配置 cuDNN ...
- mysqldump 导出提示Couldn't execute SELECT COLUMN_NAME...
mysqldump命令: 导出数据库:mysqldump -h ip -u root -p dbname > db.sql; 导出数据库中的某个表:mysqldump -h ip -u root ...
- Jenkins Slave Nodes – using the Swarm Plugin
link: http://www.donaldsimpson.co.uk/2013/03/18/jenkins-slave-nodes-using-the-swarm-plugin/ I’ve bee ...