生产者与消费者问题,java实现
2016-06-12 21:17
288 查看
import java.util.concurrent.Semaphore; public class OSTest01 { public static void main(String[] args) { // 启动线程 for (int i = 0; i <= 3; i++) { // 生产者线程 new Thread(new Producer()).start(); // 消费者线程 new Thread(new Consumer()).start(); } } // 仓库 static Warehouse buffer = new Warehouse(); // 生产者,负责增加 static class Producer implements Runnable { static int num = 1; //重写父类的run()方法 public void run() { int n = num++; while (true) { try { buffer.put(n); System.out.println(Thread.currentThread().getName()+"--------------------produce线程: " + n); // 速度较快。休息10毫秒 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } // 消费者,负责减少 static class Consumer implements Runnable { //重写父类的run()方法 public void run() { while (true) { try { System.out.println(Thread.currentThread().getName()+"-----consume线程: " + buffer.take()); // 速度较慢,休息1000毫秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } //仓库类 static class Warehouse { // 非满信号量 final Semaphore notFull = new Semaphore(10); // 非空信号量 final Semaphore notEmpty = new Semaphore(0); // 互斥信号量 final Semaphore mutex = new Semaphore(1); // 库存容量 final Object[] items = new Object[10]; int putptr, takeptr, count; //把商品放进仓库 public void put(Object x) throws InterruptedException { // 保证非满 notFull.acquire(); // 保证不冲突 mutex.acquire(); try { // 增加库存 items[putptr] = x; if (++putptr == items.length) { putptr = 0; } ++count; } finally { // 退出临界区 mutex.release(); // 增加非空信号量,允许获取商品 notEmpty.release(); } } //从仓库取出商品 public Object take() throws InterruptedException { // 保证非空 notEmpty.acquire(); // 临界区 mutex.acquire(); try { // 减少库存 Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; return x; } finally { // 退出临界区 mutex.release(); // 增加非满的信号量,允许加入商品 notFull.release(); } } } }
输出结果解释:
8个线程,其中0,2,4,6为生产者线程,1,3,5,7为消费者线程,生产前四个和消费前四个几乎是同时进行的,这些线程优先级是相同的,因此前八个输出顺序不固定的。
生产完后每个线程休眠10ms,而消费完后每个线程休眠1000ms,所以这时候只有生产者线程在运行,由于仓库有10个,所以生产者线程会生产十个,这时候由于非满信号量notFull变成0,非空信号量notEmpty变成10,因此生产者线程会等待消费者线程进行消费,当消费者线程休眠1000ms后,便会消费,也就是notEmpty会–,notFull会++,这时候生产者线程便可以继续进行生产,由于优先级一样,所以输出的顺序也是不固定的。
相关文章推荐
- spring注解
- 如何让进程运行在指定的cpu上
- Java 队列2:循环队列
- 在struts2中默认执行的execute方法
- Java命令——javap
- java排序之快速排序
- 初始static关键字
- 使用jackson解析二维数组
- 《JAVA与模式》之状态模式
- Java里length,length(),size()区别
- Spring 事务
- Java配置环境变量
- 《JAVA与模式》之策略模式
- 深入Java集合:HashMap实现原理
- struts2的action从request获取参数值的两种方式
- [转载]11条Java异常处理的最佳实践
- Struts2 result type(结果类型)
- java反射如何提升性能
- Spring框架及IOC容器
- java基础-mysql