生产者与消费者问题:

第一步:把架子搭起来

package com.zhj.www;public class ProceduerConsumer {public static void main(String[] args) {}
}//馒头实体
class wotou{int id;wotou(int id) {this.id = id;}public String toString() {return "wotou : "+id;}}
//馒头栈
class syncStack{int index = 0;wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头syncStack(int index) {this.index = index;}//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,public synchronized void push(wotou wt) {arrWT[index] = wt;    /*这两行不能分开index++;               */}//从里面取馒头,拿最上面的那一个public synchronized wotou pop() {index--;return arrWT[index];}}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{syncStack  ss= null;proceduer(syncStack ss) {this.ss = ss;}/*run方法对应着生产过程*/public void run() {for(int i =0;i<20;i++) {wotou wt = new wotou(i);ss.push(wt);}}
}
//消费者
class consumer implements Runnable{syncStack  ss= null;consumer(syncStack ss) {this.ss = ss;}public void run() {for(int i =0;i<20;i++) {wotou wotou  =ss.pop();System.out.println(wotou);}}
}

第二步:

需要考虑当馒头筐满了怎么办?马上就会报错?在push方法里考虑,让这个线程休息一下;

wait方法来源于object;wait的时候这把锁也就不属于我了。但是sleep的时候我仍然抓住这把锁。

package com.zhj.www;import java.io.IOException;public class ProceduerConsumer {public static void main(String[] args) {syncStack ss = new syncStack();proceduer proceduer = new proceduer(ss);consumer consumer  = new consumer(ss);new Thread(proceduer).start();new Thread(consumer).start();}
}//馒头实体
class wotou{int id;wotou(int id) {this.id = id;}public String toString() {return "wotou : "+id;}}
//馒头栈
class syncStack{int index = 0;wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,public synchronized void push(wotou wt)  {if(index == arrWT.length){try {this.wait();//当前对象正在执行push方法需要wait}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//哪个线程在等待就唤醒哪个线程arrWT[index] = wt;    /*这两行不能分开*/index++;                }//从里面取馒头,拿最上面的那一个public synchronized wotou pop() {if(index == 0) {try {this.wait();}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//object类里的方法,唤醒一个;index--;return arrWT[index];}}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{syncStack  ss= null;proceduer(syncStack ss) {this.ss = ss;}/*run方法对应着生产过程*/public void run() {for(int i =0;i<20;i++) {wotou wt = new wotou(i);ss.push(wt);System.out.println("生产了:"+wt);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
//消费者
class consumer implements Runnable{syncStack  ss= null;consumer(syncStack ss) {this.ss = ss;}public void run() {for(int i =0;i<20;i++) {wotou wotou  =ss.pop();System.out.println("消费了:"+wotou);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

运行过程:

可以发现生产一个馒头,就消耗一个馒头。

完善之后的栗子:

package com.zhj.www;import java.io.IOException;public class ProceduerConsumer {public static void main(String[] args) {syncStack ss = new syncStack();proceduer proceduer = new proceduer(ss);consumer consumer  = new consumer(ss);new Thread(proceduer).start();new Thread(consumer).start();}
}//馒头实体
class wotou{int id;wotou(int id) {this.id = id;}public String toString() {return "wotou : "+id;}}
//馒头栈
class syncStack{int index = 0;wotou[] arrWT= new wotou[6];//这个容器只能装6个馒头//往里仍馒头,之所以使用synchronized关键字,是因为防止多个人同时往里扔,public synchronized void push(wotou wt)  {while(index == arrWT.length){try {this.wait();//当前对象正在执行push方法需要wait}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//哪个线程在等待就唤醒哪个线程arrWT[index] = wt; /*这两行不能分开*/index++;                }//从里面取馒头,拿最上面的那一个public synchronized wotou pop() {while(index == 0) {try {this.wait();}catch (InterruptedException e) {e.printStackTrace();}}this.notify();//object类里的方法,唤醒一个;  index--;return arrWT[index];}}
/*多个生产者,也就是多个线程同时在执行*/
//生产者,用于对馒头栈的引用,他需要知道生产完馒头,需要往哪个筐里仍馒头
class proceduer implements Runnable{syncStack  ss= null;proceduer(syncStack ss) {this.ss = ss;}/*run方法对应着生产过程*/public void run() {for(int i =0;i<20;i++) {wotou wt = new wotou(i);ss.push(wt);System.out.println("生产了:"+wt);try {Thread.sleep((int)(Math.random()*200));} catch (InterruptedException e) {e.printStackTrace();}}}
}
//消费者
class consumer implements Runnable{syncStack  ss= null;consumer(syncStack ss) {this.ss = ss;}public void run() {for(int i =0;i<20;i++) {wotou wotou  =ss.pop();System.out.println("消费了:"+wotou);try {Thread.sleep((int)(Math.random()*1000));} catch (InterruptedException e) {e.printStackTrace();}}}
}

运行之后。

Java 线程多线程编程3---线程同步之生产者与消费者问题相关推荐

  1. Java 线程多线程编程2---线程同步

    来模拟一个死锁(互相等待): TestDeadLock.java package com.zhj.www;public class TestDeadLock implements Runnable { ...

  2. 多线程编程、线程同步|安全和线程通信

    多线程编程 多线程的优势 线程在程序中是独立的.并发的执行流,与分隔的进程相比,进程中的线程之间的隔离程度要小.他们共享内存.文件句柄和其他每个进程应有的状态. 因为线程的划分尺度小于进程,使得多线程 ...

  3. 廖雪峰Java11多线程编程-1线程的概念-1多线程简介

    多任务 现代操作系统(windows,MacOS,Linux)都可以执行多任务: 多任务就是同时运行多个任务,例如同时开启钉钉.百度网盘.火狐.谷歌.ps等 操作系统执行多任务就是让多个任务交替执行, ...

  4. 多线程编程之三——线程间通讯

    七.线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而 ...

  5. 多线程编程(2): 线程的创建、启动、挂起和退出

    python多线程编程(2): 线程的创建.启动.挂起和退出 如上一节,python的threading.Thread类有一个run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法.而创建 ...

  6. C#多线程编程实例 线程与窗体交互

    C#多线程编程实例 线程与窗体交互 代码: public partial class Form1 : Form{//声明线程数组Thread[] workThreads = new Thread[10 ...

  7. 多线程编程:线程死锁的原因以及解决方法

    多线程编程:线程死锁的原因以及解决方法 关于线程死锁这个问题相信程序员在编写多线程程序时会经常遇到的一个经典问题,这种情况往往出现在多个线程同时对临界资源访问时所产生的. 属于临界资源的硬件有打印机. ...

  8. Python多线程编程之线程子类化

    Python多线程编程之线程子类化 基本思路 Threading模块简介 **MyThread**主要代码 实例 所有代码 运行结果 基本思路 导入Threading模块下的Thread类,将其子类化 ...

  9. Java 并发 多线程:创建线程的四种方式

    Java 并发 多线程: 创建线程的四种方式 继承 Thread 类并重写 run 方法 实现 Runnable 接口 实现 Callable 接口 使用线程池的方式创建 1. 通过继承 Thread ...

最新文章

  1. GPU — 物理 GPU 虚拟化技术
  2. STM32 电机教程 22 - 基于ST MCLIB无感FOC算法变有感(HALL)FOC算法
  3. mysql for update 锁_MySql FOR UPDATE 锁的一点问题……
  4. android判断点击次数_Android应用统计-使用时长及次数统计(一)
  5. 优秀程序员都有哪些编程习惯?
  6. 控件内部显示不正确原因---没有调用layoutSubview的父类方法
  7. C# Windows Phone App 开发,自制LockScreen 锁定画面类别(Class),从【网路图片】、【Assets资源】、【UI】修改锁定画面。...
  8. 计算机插本2a院校,广东省专插本2A院校有哪些
  9. 室外AIS天线AV400
  10. lg g7 刷机 救砖 root
  11. 中国移动CMPP接口
  12. html怎么把图片的图层,PS制作-把图片添加到图层的4种方法
  13. vc语言c1083错误,关于VC编译错误fatal error C1083的解决办法
  14. IllegalArgumentException: error Type referred to is not an annotation type:
  15. PHP笔记——开发工具VS Code
  16. cesium添加填充_cesium实现注记功能
  17. DROID-SLAM: 用于单目双目RGBD相机的深度视觉SLAM
  18. AtCoder Beginner Contest 153 题解
  19. 李阳英语228句口语要素 +校园英语迷你惯用语 +1000句最常用英语口语
  20. 微信提示:非微信官方网页,需点继续访问才能打开网页的解决方案

热门文章

  1. c++排序算法ppt_C/C++学习教程:C语言排序算法—插入排序算法
  2. @Autowired @Resource @Inject 自动注入
  3. 蓝桥 BEGIN4 - Fibonacci数列
  4. 如何改变XCode的默认设置
  5. 无忧开通了博客园博客主页
  6. loadrunner11录制不成功解决方法(收集)
  7. Android下实现GPS定位服务
  8. css文件修改后没变化 static_Go Web编程使用Go语言创建静态文件服务器
  9. dual mysql 获取序列_MySQL JDBC客户端反序列化漏洞
  10. 安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化