java多线程--生产者和消费者模型
2016-01-12 12:28
477 查看
在开始我们先介绍wait和notifyAll这两个方法。这两个方法是Object类的方法,并且是native方法。
(1)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象锁。
(2)调用notifyAll()方法能够唤醒所有正在等待这个对象的锁线程;只能唤醒等待该想拥有该对象锁的线程,因此我们需要保证对象的同一性。
生产者代码:
消费者
主函数
(1)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象锁。
(2)调用notifyAll()方法能够唤醒所有正在等待这个对象的锁线程;只能唤醒等待该想拥有该对象锁的线程,因此我们需要保证对象的同一性。
生产者代码:
public Producer implements Runnable{ /**生产出来苹果剩余数量*/ public static int remainCount = 0; /**总共生产的苹果数量*/ public static int pCount = 0; /**苹果最大剩余量*/ public static int maxCount = 100; /**对象锁*/ private Object obj = null; public Producer(Object obj){ this.obj = obj; } private void producer(){ remainCount++; System.out.println(Thread.currentTread() + ":正在生产第" + (++pCount) + "苹果"); } public void run(){ while(true){ //同步代码块,持有obj对象锁 synchronized (obj) { if (remainCount < pMaxCount) { producer(); } else { try { obj.wait(); //不能唤醒自己,唤醒其他想持有该对象锁的线程 } catch (InterruptedException e) { e.printStackTrace(); } } obj.notifyAll(); } try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } } } }
消费者
public class Consumer implements Runnable { /**消费苹果的数量*/ public static int cCount = 0; private Object obj; public Consumer(Object obj) { this.obj = obj; } @Override public void run() { while (true) { //与生产者要持有相同的对象 synchronized (obj) { if (Producer.remainCount > 0) { consumer(); } else { try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } obj.notifyAll(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void consumer() { Producer.remainCount--; System.out.println(Thread.currentThread() + ":正在消费第" + (++cCount) + "个苹果"); } }
主函数
public class Main { public static void main(String[] args) { new Main().proAndcon(); } private void proAndcon() { Object obj = new Object(); //生产者和消费者要持有的对象 Thread tP1 = new Thread(new Producer(obj)); tP1.start(); Thread tP2 = new Thread(new Producer(obj)); tP2.start(); Thread tC1 = new Thread(new Consumer(obj)); tC1.start(); Thread tC2 = new Thread(new Consumer(obj)); tC2.start(); } }
相关文章推荐
- eclipse 的一些小知识
- Java中ArrayList源码解析
- Java生成文件
- Spring 无法注入静态变量,直接在静态方法中获取bean
- Windows系统下查看JDK的版本和安装路径!
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十)之Inner Classes
- 待翻译---- Understanding Spring MVC Model and Session Attributes
- [javase学习笔记]-9.2 单继承与多重继承
- Java进阶(二十二)使用FileOutputStream写入文件
- Java进阶(二十二)使用FileOutputStream写入文件
- java中创建新进程的两种方法
- MySQL与Eclipse或者MyEclipse的连接
- Spring MVC 中 怎样从一个Controller 方法跳转到另一个方法,注意是跳转,不是调用
- 你不知道的JAVA
- 让JAVA代码跑得更快
- Struts2中DMI(动态方法调用)的一些问题
- 【JavaWeb Structs2学习】 用Action接受参数
- 关于Eclipse 插件添加右键菜单的三种方法
- 【Java基础 1】Java2平台的三个版本介绍
- 【Java 理论篇 1】Java2平台的三个版本介绍