/**
* 线程通信的应用:经典例题:生产者/消费者问题
*
* 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,
* 店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员
* 会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品
* 了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
*
* 分析:
* 1. 是否是多线程问题?是,生产者线程,消费者线程
* 2. 是否有共享数据?是,店员(或产品)
* 3. 如何解决线程的安全问题?同步机制,有三种方法
* 4. 是否涉及线程的通信?是
* */
class Clerk{ private int productCount = 0;
//生产产品
public synchronized void produceProduct() { if(productCount < 20){
productCount++;
System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount + "个产品"); notify(); }else{
//等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
//消费产品
public synchronized void consumeProduct() {
if(productCount > 0){
System.out.println(Thread.currentThread().getName() + ":开始消费第" + productCount + "个产品");
productCount--; notify();
}else{
//等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
} class Producer extends Thread{//生产者 private Clerk clerk; public Producer(Clerk clerk) {
this.clerk = clerk;
} @Override
public void run() {
System.out.println(getName() + ":开始生产产品....."); while(true){ try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} clerk.produceProduct();
} }
} class Consumer extends Thread{//消费者
private Clerk clerk; public Consumer(Clerk clerk) {
this.clerk = clerk;
} @Override
public void run() {
System.out.println(getName() + ":开始消费产品....."); while(true){ try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
} clerk.consumeProduct();
}
}
} public class ProductTest { public static void main(String[] args) {
Clerk clerk = new Clerk(); Producer p1 = new Producer(clerk);
p1.setName("生产者1"); Consumer c1 = new Consumer(clerk);
c1.setName("消费者1");
Consumer c2 = new Consumer(clerk);
c2.setName("消费者2"); p1.start();
c1.start();
c2.start(); }
}

最新文章

  1. dedecms 采集规则过滤与替换
  2. ASP.Net中的Web Resource
  3. HtmlHelper用法大全
  4. 如何设置div的宽度为100%-xx px?
  5. ImportError: No module named setuptools 解决方案
  6. JavaScript中的test()方法
  7. linux基础命令学习(一)
  8. C++中的mutable关键字
  9. wpf的学习日志(一)
  10. awk内置变量 awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。
  11. 如何在Apache中配置多端口访问
  12. Xcode删除证书
  13. Android特效专辑(六)——仿QQ聊天撒花特效,无形装逼,最为致命
  14. Number和toString中的坑
  15. Description Resource Path Location Type Java compiler level does not match the version of(编译问题)
  16. Word中如何删除目录页的页码
  17. odoo8 和odoo10区别
  18. [docker]macvlan实现双vlan互通
  19. TCP连接图示
  20. Oracle 12c的可插拔数据库PDB

热门文章

  1. office组件导入导出常见异常记录
  2. qt 中使用 c 语言文件
  3. 电影网站的电影m3u8源址分享(存储于mysql数据库,可直接应用在电影网站上使用)
  4. 201912-1 报数 Java
  5. 吴裕雄--天生自然C++语言学习笔记:C++ 数据封装
  6. linux crash工具安装配置
  7. HDU - 4082 Hou Yi&#39;s secret
  8. ArchLinux安装KDE桌面
  9. float 格式化到TCHAR 数组
  10. redis常用命令--zsets