java利用多线程实现生产者和消费者功能————美的掉渣的代码

1.使用wait()/notifyAll实现生产者和消费者

 1 /**
 2  * 锁对象类
 3  * 协作类
 4  */
 5 public class MyQueue {
 6     private Queue<Integer> queue;
 7     private int limit;
 8 
 9     public MyQueue(int limit) {
10         this.queue = new ArrayDeque<>(limit);
11         this.limit = limit;
12     }
13 
14     public synchronized void put(int n) throws InterruptedException {
15         while (queue.size()==limit){
16             wait();
17         }
18         queue.add(n);
19         /**
20          * 通知所有queue上的线程(消费者线程,生产者线程)
21          */
22         notifyAll();
23     }
24     public synchronized int get() throws InterruptedException {
25         while (queue.isEmpty()){
26             wait();
27         }
28         int e=queue.poll();
29         /**
30          * 通知所有queue上的线程(消费者线程,生产者线程)
31          */
32         notifyAll();
33         return e;
34     }
35 }

 

 1 /**
 2  * 生产者线程
 3  */
 4 public class ProduceThread extends Thread {
 5     private MyQueue queue;
 6 
 7     public ProduceThread(MyQueue queue) {
 8         this.queue = queue;
 9     }
10 
11     @Override
12     public void run() {
13         int num=0;
14         while (true){
15             try {
16                 System.out.println("生产数据:" + num);
17                 queue.put(num);
18                 num++;
19                 Thread.sleep((int)(Math.random()*100));
20             } catch (InterruptedException e) {
21                 e.printStackTrace();
22             }
23         }
24     }
25 }

 

 1 /**
 2  * 消费者线程
 3  */
 4 public class ConsumerThread extends Thread {
 5     private MyQueue queue;
 6 
 7     public ConsumerThread(MyQueue queue) {
 8         this.queue = queue;
 9     }
10 
11     @Override
12     public void run() {
13        while (true){
14            try {
15                int res=queue.get();
16                System.out.println("消费数据:"+res);
17                Thread.sleep((int)(Math.random()*100));
18            } catch (InterruptedException e) {
19                e.printStackTrace();
20            }
21        }
22     }
23 }

 

 1 /**
 2  * 主线程
 3  */
 4 public class MainTest {
 5     public static void main(String[] args) {
 6         MyQueue queue=new MyQueue(100);
 7         new ProduceThread(queue).start();
 8         new ConsumerThread(queue).start();
 9     }
10 }

 

2.使用ReentrantLock和condition实现生产者和消费者功能

 1 /**
 2  * 协作类
 3  */
 4 public class MyBlockQueue {
 5     private Queue<Integer> queue=null;
 6     private int limit;
 7     private Lock lock=new ReentrantLock();
 8     private Condition produceCondition =lock.newCondition();
 9     private Condition ConsumerCondition =lock.newCondition();
10 
11     public MyBlockQueue(int limit) {
12         this.limit = limit;
13         queue=new ArrayDeque<>(limit);
14     }
15     public void put(int n) throws InterruptedException {
16         lock.lockInterruptibly();//可中断锁
17         try {
18             while (queue.size()==limit){
19                 produceCondition.await();
20             }
21             queue.add(n);
22             ConsumerCondition.signal();
23         }finally {
24             lock.unlock();
25         }
26     }
27 
28 
29     public int get() throws InterruptedException {
30         lock.lockInterruptibly();
31         try {
32             while (queue.isEmpty()){
33                 ConsumerCondition.await();
34             }
35             int e=queue.poll();
36             produceCondition.signal();
37             return  e;
38         }finally {
39             lock.unlock();
40         }
41     }
42 }

 

 1 /**
 2  * 生产者线程
 3  */
 4 public class ProduceThread extends Thread {
 5     private MyBlockQueue queue;
 6 
 7     public ProduceThread(MyBlockQueue queue) {
 8         this.queue = queue;
 9     }
10 
11     @Override
12     public void run() {
13         int num=0;
14         while (true){
15             try {
16                 System.out.println("生产数据:" + num);
17                 queue.put(num);
18                 num++;
19                 Thread.sleep((int)(Math.random()*100));
20             } catch (InterruptedException e) {
21                 e.printStackTrace();
22             }
23         }
24     }
25 }

 

 

 1 /**
 2  * 消费者线程
 3  */
 4 public class ConsumerThread extends Thread {
 5     private MyBlockQueue queue;
 6 
 7     public ConsumerThread(MyBlockQueue queue) {
 8         this.queue = queue;
 9     }
10 
11     @Override
12     public void run() {
13        while (true){
14            try {
15                int res=queue.get();
16                System.out.println("消费数据:"+res);
17                Thread.sleep((int)(Math.random()*100));
18            } catch (InterruptedException e) {
19                e.printStackTrace();
20            }
21        }
22     }
23 }

 

 1 /**
 2  * 主线程
 3  */
 4 public class MainTest {
 5     public static void main(String[] args) {
 6         MyBlockQueue queue=new MyBlockQueue(100);
 7         new ProduceThread(queue).start();
 8         new ConsumerThread(queue).start();
 9     }
10 }

 

分析:wait/notify只能实现一个条件队列;准备唤醒生产者队列,却把消费者也唤醒了;相互竞争后最终生产者满足条件,开始执行,消费者再次变成等待状态。

而使用显示锁,则可以创建多条等待队列。

 

posted @ 2020-07-18 12:10  思思博士  阅读(522)  评论(0编辑  收藏  举报