美文网首页
多线程-多生产者多消费者模型

多线程-多生产者多消费者模型

作者: 谢谢那些曾经丶 | 来源:发表于2018-05-04 20:32 被阅读0次

多线程中比较经典的就是生产者消费者模式了,很多复杂的模式也是在这个基础上演变的。里面也又很多的小知识点。

生产者消费者代码
public class AssemblyLine<T> {
//存放生产数据的队列
private final List<T> queue;
//最大生产值
private final int queueMaxSize;

public AssemblyLine(List<T> messageQueue, int max) {
    this.queue = messageQueue;
    this.queueMaxSize = max;
}
//生产者
public void produceMessage(T message) {
    synchronized (queue){
        while (queue.size()>=queueMaxSize){
            try {
                queue.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+":produce:"+message);
        queue.add(message);
        queue.notifyAll();
    }
}
//消费者
public void consumeMessage(){
    synchronized (queue){
        while (queue.isEmpty()){
            try {
                queue.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+":consume:"+ queue.remove(0));
        queue.notifyAll();
    }
}
执行代码
public class Test {
public static void main(String[] args) {
    final List<String> messageQueue=new LinkedList<>();
    final int MAX_PRODUCE_SIZE=20;
    AssemblyLine<String> assemblyLine = new AssemblyLine<>(messageQueue,   MAX_PRODUCE_SIZE);
    Stream.of("produce1","produce2","produce3").forEach(s ->
        new Thread(()-> {
            while (true){
                assemblyLine.produceMessage(UUID.randomUUID().toString());
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },s).start()
    );
    Stream.of("consume1","consume2").forEach(s ->
        new Thread(()->{
            while (true){
                assemblyLine.consumeMessage();
                try {
                    TimeUnit.MILLISECONDS.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },s).start()
    );
}
总结
  • 在生产者消费者模型中判断逻辑代码中不能使用if必须使用while,因为需要被唤醒后的生产者或者消费者去重新执行判断,否则可能一次生成多次消费,生成过剩的情况发生。
  • 因为Object.notify()不能指定唤醒某个等待的线程,所以只能使用notifyAll();

相关文章

网友评论

      本文标题:多线程-多生产者多消费者模型

      本文链接:https://www.haomeiwen.com/subject/gsdjrftx.html