最近在研究wait和notify方法,发现有个地方要注意,但是网上又说得不是很明白的地方,就是经典的生产者和消费模式,使用wait和notify实现,判断list是否为空的这个为什么要用while而不能使用if呢?其实是因为当线程wait之后,又被唤醒的时候,是从wait后面开始执行,而不是又从头开始执行的,所以如果用if的话,被唤醒之后就不会在判断if中的条件,而是继续往下执行了,如果list只是添加了一个数据,而存在两个消费者被唤醒的话,就会出现溢出的问题了,因为不会在判断size是否==0就直接执行remove了。但是如果使用while的话,从wait下面继续执行,还会返回执行while的条件判断,size>0了才会执行remove操作,所以这个必须使用while,而不能使用if来作为判断。

    以下代码是一个简单的实践,参考:http://www.cnblogs.com/hapjin/p/5492645.html(做了适当的调整)
     Add类,负责添加数据:

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();
}
}

  

 
    Subtract类,负责删除数据
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();
}
}

  

 
    封装的List队列:
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();
}
}
 

最新文章

  1. make things simple
  2. mysql备份脚本,每天执行一次全量备份,三次增量备份
  3. Cookie对象工具包,对象添加,获取,修改-亲测可用
  4. mysql 信息查询
  5. 如何解读SQL Server日志(2/3)
  6. Unity3d 提示 "The scripts file name does not match the name of the class defined in the script!"的解决办法
  7. django 一些库
  8. std::map 自定义排序
  9. html --- ajax --- javascript --- 简单的封装
  10. send,recv,sendto,recvfrom
  11. android.os.NetworkOnMainThreadException 异常处理
  12. DateDiff 函数,用生日获得年龄
  13. WCF 项目应用连载[3] - 双向通信 实例管理与服务端监控
  14. Python HiveServer2
  15. 最近因为textview高度问题疯了疯了疯了
  16. 记录一次因为硬盘写满造成的redis无法连接
  17. 2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)
  18. React-Native安装使用
  19. 在腾讯云(windows)上搭建node.js服务器
  20. LuoGu P1352 没有上司的舞会

热门文章

  1. sql获取表的所有字段及属性
  2. mongodb工具类
  3. 点击隐藏显示和点击body空白处隐藏
  4. 9、select 语句
  5. ARX项目中添加开源数据库SQLite3 的加密开源库wxsqlite3
  6. windows下安装ubuntu15.04
  7. 最短路 CF954D Fight Against Traffic
  8. leetcode-766-Toeplitz Matrix(每一条对角线元素的比较)
  9. js 实现全国省市区三级联动
  10. Gsteramer 环境配置