当前位置: 代码迷 >> 综合 >> 轻松学习多线程-06-Producer Consumer 模式
  详细解决方案

轻松学习多线程-06-Producer Consumer 模式

热度:47   发布时间:2024-01-06 11:21:46.0

Producer Consumer 模式

Producer Consumer 模式是指一个负责生产,一个负责消费。

核心是生产者安全地将数据交给消费者。

实际案例

类信息概览:

类名 说明
Main.java 方法的总入口
ConsumerCakeThread.java 消费蛋糕的线程
Table.java 放置蛋糕的桌子
BlockingQueueTable.java BlockingQueue 实现
ProducerCakeThread.java 生产蛋糕的线程

定义

  • ConsumerCakeThread.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;import java.util.Random;public class ConsumerCakeThread extends Thread {
    private String name;private final Table table;public ConsumerCakeThread(String name, Table table) {super(name);this.table = table;}@Overridepublic void run() {Random random = new Random(1000L);try {while(true) {Thread.sleep(random.nextInt(1000));String cake = table.take();}} catch (InterruptedException e) {e.printStackTrace();}}}
  • Table.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;/*** @see BlockingQueueTable 可以被这个替换*/
public class Table {
    /*** 存放蛋糕的数组*/private String[] cakeArray;/*** 头*/private int head;/*** 尾巴*/private int tail;private int count;private final int size;public Table(int size) {this.size = size;cakeArray = new String[size];this.head = 0;this.tail = 0;this.count = 0;}public synchronized void put(final String cakeName) throws InterruptedException {while(count >= size) {wait();}cakeArray[tail] = cakeName;count++;tail = (tail + 1) % size;System.out.println(Thread.currentThread().getName() + " put cake " + cakeName);notifyAll();}public synchronized String take() throws InterruptedException {while (count <= 0) {wait();}String result = cakeArray[head];head = (head + 1) % size;count--;System.out.println(Thread.currentThread().getName() + " take cake " + result);notifyAll();return result;}}
  • BlockingQueueTable.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;import java.util.concurrent.ArrayBlockingQueue;/*** 使用 queue*/
public class BlockingQueueTable extends ArrayBlockingQueue<String> {
    public BlockingQueueTable(int size) {super(size);}public void put(final String cakeName) throws InterruptedException {super.put(cakeName);}public String take() throws InterruptedException {return super.take();}}
  • ProducerCakeThread.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;import java.util.Random;public class ProducerCakeThread extends Thread {
    private final Table table;private static int id = 0;public ProducerCakeThread(String name, Table table) {super(name);this.table = table;}@Overridepublic void run() {Random random = new Random(1000L);try {while(true) {String cakeName = getName()+"-"+genId();Thread.sleep(random.nextInt(1000));table.put(cakeName);}} catch (InterruptedException e) {e.printStackTrace();}}private static synchronized int genId() {return id++;}}

测试

  • Main.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;public class Main {
    public static void main(String[] args) {Table table = new Table(3);new ConsumerCakeThread("ConsumerCake", table).start();new ProducerCakeThread("ProducerCake", table).start();}}
  • 测试结果
ProducerCake put cake ProducerCake-0
ConsumerCake take cake ProducerCake-0
ProducerCake put cake ProducerCake-1
ConsumerCake take cake ProducerCake-1
ProducerCake put cake ProducerCake-2
ConsumerCake take cake ProducerCake-2
ProducerCake put cake ProducerCake-3
ConsumerCake take cake ProducerCake-3
ProducerCake put cake ProducerCake-4
ConsumerCake take cake ProducerCake-4
ProducerCake put cake ProducerCake-5
ConsumerCake take cake ProducerCake-5

实现方式

UML & Code

UML

UML 图示如下

Producer Consumer

Code

代码地址

Producer Consumer

系列导航

多线程系列导航

  相关解决方案