在同步块中调用 wait() 和 notify()方法,如果阻塞,通过循环来测试等待条件。请参考答案中的示例代码。

【生产者】

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger; public class Producer implements Runnable { private final Vector sharedQueue;
private final int SIZE; public Producer(Vector sharedQueue, int size) {
this.sharedQueue = sharedQueue;
this.SIZE = size;
} @Override
public void run() {
// 生产数据
for (int i = 0; i < 7; i++) {
System.out.println("Produced:" + i);
try {
produce(i);
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
}
}
} private void produce(int i) throws InterruptedException { // wait if queue is full
while (sharedQueue.size() == SIZE) {
synchronized (sharedQueue) {
System.out.println("Queue is full " + Thread.currentThread().getName()
+ " is waiting , size: " + sharedQueue.size());
sharedQueue.wait();
}
} // producing element and notify consumers
synchronized (sharedQueue) {
sharedQueue.add(i);
sharedQueue.notifyAll();
}
}
}

【消费者】

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger; public class Consumer implements Runnable { private final Vector sharedQueue;
private final int SIZE; public Consumer(Vector sharedQueue, int size) {
this.sharedQueue = sharedQueue;
this.SIZE = size;
} @Override
public void run() {
// 消费数据
while (true) {
try {
System.out.println("Consumer: " + consume());
Thread.sleep(50);
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
} private int consume() throws InterruptedException { // wait if queue is empty
while (sharedQueue.isEmpty()) {
synchronized (sharedQueue) {
System.out.println("Queue is empty " + Thread.currentThread().getName()
+ " is waiting , size: " + sharedQueue.size());
sharedQueue.wait();
}
} //otherwise consume element and notify waiting producer
synchronized (sharedQueue) {
sharedQueue.notifyAll();
return (Integer) sharedQueue.remove(0);
}
}
}

【测试函数】

import java.util.Vector;

public class ProducerConsumerSolution {

    public static void main(String[] args) {
Vector sharedQueue = new Vector();
int size = 4;
Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer");
Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer");
prodThread.start();
consThread.start();
}
}

运行结果:

Produced:0
Queue is empty Consumer is waiting , size: 0
Produced:1
Consumer: 0
Produced:2
Produced:3
Produced:4
Produced:5
Queue is full Producer is waiting , size: 4
Consumer: 1
Produced:6
Queue is full Producer is waiting , size: 4
Consumer: 2
Consumer: 3
Consumer: 4
Consumer: 5
Consumer: 6
Queue is empty Consumer is waiting , size: 0

最新文章

  1. JQuery 滚动轮播
  2. CentOS 7安装Mysql并设置开机自启动
  3. 深入了解iPad上的MouseEvent【转】
  4. 关于String和StringBuffer的使用
  5. JDK_Proxy_InvocationHandler_动态代理
  6. 清除Android工程中没用到的资源(转)
  7. 转:Loadrunner上传文件解决办法(大文件)
  8. 用户登录(Material Design + Data-Binding + MVP架构模式)实现
  9. Using Sass with the Angular CLI
  10. JavaScript继承的几种模式
  11. Flask从入门到精通
  12. nginx_server_location对客户资源的辨别规则
  13. iOS蓝色和黄色文件夹新建方式区别(区别之前)
  14. [转载] Oracle之内存结构(SGA、PGA)
  15. 第 3 章 镜像 - 015 - 调试 Dockerfile
  16. 使用MSTSC远程登录时提示证书无效的解决方法
  17. 在Eclipse中给JRE-Library添加本地Javadoc
  18. Vue实例对象的数据选项(火柴)
  19. javac -cp java -cp
  20. 【套题】qbxt国庆刷题班D1

热门文章

  1. sublime text3中emmet插件的使用
  2. vmware提示请卸载干净再重新安装的解决办法
  3. 11-30 js高级
  4. Mac删除默认美国输入法
  5. Scala详解
  6. jquery的deferred使用详解
  7. 关于IP,这里有你想知道的一切!
  8. Keras/Tensorflow选择GPU/CPU运行
  9. Python数据预处理:机器学习、人工智能通用技术(1)
  10. PL/SQL学习笔记程序单元