生产者消费者模型是线程模型中一个经典问题:生产者和消费者在同一时间内共享同一个容器,生产者向容器添加产品,消费者从容器中取走产品,当容器满时,生产者阻塞,当容器为空时,消费者阻塞。
一、Code
1.1 synchronized实现
1.1.1 容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class Container { private Queue<Integer> container = new LinkedList<>(); private int containerSize = 5;
public synchronized void add(int val) throws InterruptedException { if (container.size() > containerSize) { wait(); } container.add(val); notify(); }
public synchronized int get() throws InterruptedException { if (container.size() == 0) { wait(); } int returnRes = container.poll(); notify(); return returnRes; } }
|
1.1.2 生产者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Producer extends Thread{ private Container container;
public Producer(Container container) { this.container = container; }
@Override public void run() { for (int i = 0; i < 10; i++) { try { container.add(i); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
|
1.1.3 消费者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Consumer extends Thread { private Container container;
public Consumer(Container container) { this.container = container; }
@Override public void run() { for (int i = 0; i < 10; i++) { int val = 0; try { val = container.get(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(val); } } }
|
1.1.4 Demo
1 2 3 4 5 6 7 8 9
| public class ProducerAndConsumerDemo { public static void main(String[] args) { Container container = new Container(); Producer producer = new Producer(container); Consumer consumer = new Consumer(container); producer.start(); consumer.start(); } }
|
1.2 BlockingQueue实现
使用BlockingQueue时,我们再也不必关心什么时候应该阻塞线程,什么时候应该唤醒线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| package com.cc.step1.ProducerAndConsumerModel;
import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
public class PCByBlockingQueue { private static int count = 0;
private final BlockingQueue blockingQueue = new LinkedBlockingQueue(10);
class Producer implements Runnable {
@Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } try { int val = new Random().nextInt(1000); blockingQueue.put(val); count++; System.out.println(Thread.currentThread().getName() + "-生产者生产" + val + ",容器中数量为:" + count); } catch (InterruptedException e) { e.printStackTrace(); } } } }
class Consumer implements Runnable {
@Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(new Random().nextInt(500)); } catch (InterruptedException e) { e.printStackTrace(); } try { int val = (int) blockingQueue.take(); count--; System.out.println(Thread.currentThread().getName() + "-消费者消费" + val + ",容器中数量为:" + count); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public static void main(String[] args) { PCByBlockingQueue blockingQueueTest = new PCByBlockingQueue(); new Thread(blockingQueueTest.new Producer()).start(); new Thread(blockingQueueTest.new Consumer()).start();
} }
|
参考
➱ https://www.jianshu.com/p/f53fb95b5820
发布时间: 2020-11-23 1:03:24
更新时间: 2022-04-21 14:35:15
本文链接: https://wyatt.ink/posts/Code/161dcf21.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!