多线程环境下,我们经常需要多个线程的并发和协作。这个时候,就需要了解一个重要 的多线程并发协作模型“生产者/消费者模式”。

  1. 生产者:生产者指的是负责生产数据的模块。
  2. 消费者:消费者指的是负责处理数据的模块。
  3. 缓冲区:消费者不能直接使用生产者的数据,它们之间有个“缓冲区”。生产者将生产好的数据 放入“缓冲区”,消费者从“缓冲区”拿要处理的数据。
    线程并发协作(生产者/消费者模式)馒头案例_数据
    缓冲区是实现并发的核心,缓冲区的设置有两个好处:
    1.实现线程的并发协作 有了缓冲区以后,生产者线程只需要往缓冲区里面放置数据,而不需要管消费者消 费的情况;同样,消费者只需要从缓冲区拿数据处理即可,也不需要管生产者生产的情 况。 这样,就从逻辑上实现了“生产者线程”和“消费者线程”的分离,解除了生产 者与消费者之间的耦合。
    2.解决忙闲不均,提高效率 生产者生产数据慢时,缓冲区仍有数据,不影响消费者消费;消费者处理数据慢时,生 产者仍然可以继续往缓冲区里面放置数据 。
package com.yqq.app12;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* @Author yqq
* @Date 2021/11/28 23:52
* @Version 1.0
*/

/**
* 馒头类
*/
@AllArgsConstructor
@Getter
class ManTou{
private int id;

}

/**
* 定义缓冲区类
*/
class SyscStack{
//定义存储馒头的数组
private ManTou[] mt = new ManTou[10];
//定义操作盒子的索引
private int index;
/**
* 放馒头
*/
public synchronized void push(ManTou manTou){
//判断盒子是否已经满
while (this.index == this.mt.length){
try {
this.wait();//wait执行后,会释放锁,进入阻塞状态,
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//唤醒放馒头线程
this.notify();
this.mt[this.index] = manTou;
this.index++;
}
/**
* 取馒头
*/
public synchronized ManTou pop(){
while (this.index == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//唤醒取馒头线程
this.notify();//该方法会唤醒处于等待状态队列中的线程
this.index--;
return this.mt[this.index];
}
}

/**
* 生产线程
*/
class Producer extends Thread{
private SyscStack syscStack;
public Producer(SyscStack syscStack){
this.syscStack = syscStack;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("生产馒头"+i);
ManTou manTou = new ManTou(i);
this.syscStack.push(manTou);
}
}
}

/**
* 消费者线程
*/
class Consumer extends Thread{
private SyscStack syscStack;
public Consumer(SyscStack syscStack){
this.syscStack = syscStack;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
ManTou manTou = this.syscStack.pop();
System.out.println("取馒头"+i);
}
}
}
public class ProduceThread {
public static void main(String[] args) {
SyscStack ss = new SyscStack();
new Producer(ss).start();
new Consumer(ss).start();
}
}

线程并发协作(生产者/消费者模式)馒头案例_等待状态_02
线程并发协作总结:
线程并发协作(也叫线程通信)。 生产者消费者模式:

  1. 生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条 件。
  2. 对于生产者,没有生产产品之前,消费者要进入等待状态。而生产了产品之后, 又需要马上通知消费者消费。
  3. 对于消费者,在消费之后,要通知生产者已经消费结束,需要继续生产新产品 以供消费。
  4. 在生产者消费者问题中,仅有 synchronized 是不够的。 synchronized 可阻止并发更新同一个共享资源,实现了同步但是 synchronized
  5. 那线程是通过哪些方法来进行消息传递(通信)的呢?见如下总结:
    线程并发协作(生产者/消费者模式)馒头案例_数据_03