使用wait/notify来实现生产者消费者时能够达到在线程阻塞的效果,这样就不会出现轮询,然后浪费cpu时间的目的。代码如下:
1. 状态类,表示是否已经生产:

 package com.demo;

 public class State {

     public State() {
flag = false;
} public boolean flag;
}

State.java

2. 生产者类:

 package com.demo;

 public class Productor extends Thread {

     public com.demo.State state;

     @Override
public void run() {
for(int i=0; i<10;) {
try {
synchronized(state) {
if(state.flag) {
state.wait();
} else {
System.out.println("product: " + i);
i++;
state.flag = true;
state.notify();
}
}
}
catch(Exception ex) { }
}
}
}

Productor.java

3. 消费者类:

 package com.demo;

 public class Consumer extends Thread {

     public com.demo.State state;

     public void run(){
for(int i=0; i<10;) {
try {
synchronized(state) {
if(!state.flag) {
state.wait();
} else {
System.out.println("consumer: " + i);
i++;
state.flag = false;
state.notify();
}
}
}
catch(Exception ex) { }
}
}
}

Consumer.java

4. 测试类

 package com.demo;

 public class Program {

     public static void main(String[] args) throws Exception {
State state = new State();
Productor productor = new Productor();
productor.state = state;
Consumer consumer = new Consumer();
consumer.state = state;
Thread th1 = new Thread(productor);
Thread th2 = new Thread(consumer);
th1.start();
th2.start();
th1.join();
th2.join();
}
}

Program.java

在生产者和消费者每次执行的时候总是先判断state.flag的状态,为false表示已经没有生产,这样消费者应该等待,而生产者应该生产;为true表示已经生产,这样生产者应该等待,而消费者应该消费。而这生产者生产了后将flag设置为true,这样就表示已经生产了,然后通知消费者,这样生产者再次执行的时候发现消费者还没消费的话就处于阻塞状态,而消费者在收到通知后就开始消费过程,然后将flag设置为false,再通知生产者,如此周而复始。
使用wait/notify可能会应为线程的执行的先后顺序不同而造成死锁,而在本实现中是通过同一个对象的flag属性的真假来判断的,所以即便执行顺序不一致,也不会出现消费者先于生产者生产前消费,所以也就避免了死锁。

最新文章

  1. typeof的一些兼容性问题
  2. 11.12模拟考T2(GCD)
  3. 甘特图和PERT图
  4. dictionaryWithObjectsAndKeys
  5. 如何实现从Android第三方平台推送微信公众号
  6. 面对一个&ldquo;丢失了与用户&ldquo;签订&rdquo;的协议的修改&rdquo;时进行的思考。
  7. oracle中DECODE与CASE的用法区别
  8. 1053: [HAOI2007]反素数ant - BZOJ
  9. MSBuild could not create or connect to a task host with runtime &quot;CLR2&quot; and architecture &quot;x86&quot;.
  10. Hadoop下各技术应用场景
  11. 今天写动态canvas柱状图小结
  12. CentOS7 部署 tomcat
  13. 更改zendstudio花括号匹配显示的方法
  14. Asp.net MVC 简单实现生成Excel并下载
  15. jdbc、Mybatis插入数据主键回显的实现方法
  16. AOV网络和Kahn算法拓扑排序
  17. MFC 程序入口和执行流程
  18. search_response.go
  19. http跳转https
  20. Docker 修改默认存储路径的一个方法

热门文章

  1. js中的setTimeout第三个参数
  2. prototype和__proto__的关系是什么
  3. css样式 + 特殊符号
  4. 垃圾收集器(GC)
  5. C#获取文件目录
  6. 用Windows命令行编译自己的c或者cpp以及一些操作
  7. 手把手教你用git
  8. emmet简单记录
  9. Spring mvc 加载HTML静态页面
  10. node 创建server 及加载静态页面