生产者与消费者问题研究
来源:互联网 发布:中博软件学院 编辑:程序博客网 时间:2024/06/01 10:32
首先模拟单缓冲区生产者和消费者问题,wait()通常都要放入synchronized修饰的语句块中或者方法中,唤醒该线程需要调用同一对象的notify()或者notifyAll()方法
当调用某个对象notify()方法时,将从该对象等待集合中选择一个等待的线程唤醒,唤醒的线程将从等待集合中删除。
notifyAll是唤醒所有线程,只不过由于synchronized,最终只有一个线程进入
class basket{private boolean empty;private int good;public basket(){empty=true;//一开始篮子是空的}public synchronized void put(int value){//放入重量为value的内容while(!empty){//当篮子不为空时try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}good=value;System.out.println("往篮子里面放入"+good);empty=false;notify();}public synchronized void get(){//取物品while(empty){try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println("从篮子里面获得"+good);empty=true;notify();}}class producer implements Runnable{private basket b=new basket();public producer(basket b){this.b=b;}public void run(){ for (int i=1;i<=10;i++) b.put((int)(Math.random()*100));}}class consumer implements Runnable{ private basket b=new basket(); public consumer(basket b){ this.b=b; } public void run(){for (int i=1;i<=10;i++) b.get(); }}public class test8 {public static void main(String[] args) { basket b=new basket(); producer p=new producer(b); Thread t1=new Thread(p); consumer c=new consumer(b); Thread t2=new Thread(c); t1.start(); t2.start();} }对于多缓冲区需要借助循环队列来实现存储
class basket2{private int []a;//存储缓冲区private int front;//队首private int rear;//队尾public basket2(){//初始化存储区a=new int[10];front=0;rear=0;}public boolean isEmpty(){return front==rear;}public boolean isfull(){return (front+1)%10==rear;}public synchronized void put(int goods){//为满的时候循环等待while(isfull()){try {wait();} catch (InterruptedException e) {e.printStackTrace();}} front=(front+1)%10; a[front]=goods; System.out.println("生产者放入"+goods); notify();}public synchronized void get(){while(isEmpty()){try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}rear=(rear+1)%10;System.out.println("消费者取出"+a[rear]);notify(); }}class producer2 extends Thread{private basket2 b=new basket2();public producer2(basket2 b){this.b=b;}public void run(){for (int i=1;i<=100;i++)b.put((int)(Math.random()*100));}}class consumer2 extends Thread{private basket2 b=new basket2();public consumer2(basket2 b){this.b=b;}public void run(){for (int i=1;i<=100;i++)b.get();}}public class test9 {//一个生产者和消费者共用多个缓冲区 public static void main(String[] args) {basket2 b=new basket2();producer2 p=new producer2(b);consumer2 c=new consumer2(b);p.start();c.start();}}
JDK1.5之后引入条件变量:
synchronized被Lock锁替换后,对应的监视方法wait,notify,notifyAll也要用awit,signal,signalAll操作替换。
class basket2{private int []a;//存储缓冲区private int front;//队首private int rear;//队尾private Lock lock;private Condition full;private Condition empty;public basket2(){//初始化存储区a=new int[10];front=0;rear=0;lock=new ReentrantLock();empty=lock.newCondition();full=lock.newCondition();}public boolean isEmpty(){return front==rear;}public boolean isfull(){return (front+1)%10==rear;}public void put(int goods){//为满的时候循环等待lock.lock();while(isfull()){try {full.await();} catch (InterruptedException e) {e.printStackTrace();}} front=(front+1)%10; a[front]=goods; System.out.println("生产者放入"+goods); empty.signal(); lock.unlock();}public void get(){lock.lock();while(isEmpty()){try {empty.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}rear=(rear+1)%10;System.out.println("消费者取出"+a[rear]);full.signal(); lock.unlock(); }}class producer2 extends Thread{private basket2 b=new basket2();public producer2(basket2 b){this.b=b;}public void run(){for (int i=1;i<=100;i++)b.put((int)(Math.random()*100));}}class consumer2 extends Thread{private basket2 b=new basket2();public consumer2(basket2 b){this.b=b;}public void run(){for (int i=1;i<=100;i++)b.get();}}public class test9 {//一个生产者和消费者共用多个缓冲区 public static void main(String[] args) {basket2 b=new basket2();producer2 p=new producer2(b);consumer2 c=new consumer2(b);p.start();c.start();}}
java并发库中有一些线程安全的集合,比如可以使用ConcurrentLinkedDeque()来解决多缓冲区的生产者和消费者问题。
class basket3{ private ConcurrentLinkedDeque<Integer>list=new ConcurrentLinkedDeque<Integer>(); public void put(int n){ list.add(n); System.out.println("向列表中装入"+n); } public void get(){ while(!list.isEmpty()) System.out.println("从列表中移除"+list.pollFirst()); }}class Producer2 implements Runnable{basket3 b=new basket3();public Producer2(basket3 b){this.b=b;}public void run(){for (int i=1;i<=10;i++)b.put((int)(Math.random()*100));}}class Consumer2 implements Runnable{basket3 b=new basket3();private Thread t;public Consumer2(basket3 b,Thread t1){this.b=b;t=t1;}public void run(){try {t.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}for (int i=1;i<=10;i++)b.get();}} public class test10 { public static void main(String[] args) {basket3 b=new basket3();Thread t1=new Thread(new Producer2(b));Thread t2=new Thread(new Consumer2(b,t1));t1.start();t2.start();}}
0 0
- 生产者与消费者问题研究
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 消费者与生产者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 消费者与生产者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- 生产者与消费者问题
- java生产者与消费者问题
- 消费者与生产者问题代码
- Android 注解的使用 xUtils3和ButterKnife控件的注解注入对比
- 数组解简单多次递归
- 在LINUX下探测硬件信息的命令
- Rails控制台出现current transaction is aborted错误的解决
- [BZOJ1086][SCOI2005]王室联邦(树上分块)
- 生产者与消费者问题研究
- 深入浅出搜索架构引擎、方案与细节(上)
- 浅谈C++指针
- PHP学习杂记(一)
- 记忆化搜索(字符串)——Kickstart 2017(Google Code Jam) A Round #B
- caffe下用个多模型对图片批量分类
- 冒泡排序
- redis若干问题
- Path类的最全面详解