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

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

生产者消费者代码
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();
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 线程间的通信与生产者消费者模型 在前面我们讲了很多关于同步的问题,然而在现实中,需要线程之间的协作。比如说最经典的...
    史路比阅读 281评论 0 0
  • 【 线程间的通讯 wait()在对象上等待,等待通知(在等待过程中释放对象锁、等待必须在同步块内、这个对象就是同步...
    征程_Journey阅读 716评论 0 0
  • 题图 两个线程一个生产者个一个消费者 需求情景 涉及问题 代码实现(共三个类和一个main方法的测试类) 多个线程...
    极乐君阅读 514评论 0 4
  • 【JAVA 线程】 线程 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者...
    Rtia阅读 2,783评论 2 20
  • 十三岁,可以做什么? 十三岁的他拥有了他的国度,尽管他可能只是扯线木偶。但是不重要,踏上宝座的那一天,他已是...
    叶良浩阅读 2,238评论 1 11