`
bit1129
  • 浏览: 1069849 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Java多线程二】多路条件解决生产者消费者问题

 
阅读更多
package com.tom;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Plate<T> {
    private final Lock lock = new ReentrantLock();
    private final Condition PLATE_NOT_FULL = lock.newCondition();
    private final Condition PLATE_NOT_EMPTY = lock.newCondition();

    private final Queue<T> plates = new LinkedList<T>();
    private int size;

    public Plate(int size) {
        this.size = size;
    }

    public void produce(T fruit) {
        lock.lock();
        try {
            if (plates.size() >= size) {
                try {
                    System.out.println(Thread.currentThread().getName() + ", The plate is full..waiting to put into the plate");
                    PLATE_NOT_FULL.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + ", The plate is not full..put the fruit  into the plate: " + fruit);
            plates.offer(fruit);
            PLATE_NOT_EMPTY.signalAll();
        } finally {
            if (lock != null){
                lock.unlock();
            }
        }

    }

    public T consume() {
        T fruit = null;
        lock.lock();
        try {
            if (plates.isEmpty()) {
                try {
                    System.out.println(Thread.currentThread().getName() + ", The plate is empty..waiting to consume");
                    PLATE_NOT_EMPTY.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            fruit = plates.poll();
            System.out.println(Thread.currentThread().getName() + ",The plate is not empty, consume the fruit: " + fruit);
            PLATE_NOT_FULL.signalAll();
        } finally {
            if (lock != null){
                lock.unlock();
            }
        }

        return fruit;
    }

}

public class ThreadCommunication {

    private static volatile boolean shutdown = false;

    public static void main(String[] args) {

        final Plate<Integer> plate = new Plate<Integer>(8);

        Thread[] consumers = new Thread[3];

        for (int i = 0; i < consumers.length; i++) {

            consumers[i] = new Thread() {
                @Override
                public void run() {

                    while (!shutdown) {
                        plate.consume();
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            };
            consumers[i].start();
        }


        Thread[] producers = new Thread[2];

        for (int i = 0; i < producers.length; i++) {
            producers[i] = new Thread() {
                @Override
                public void run() {
                    while (!shutdown) {
                        plate.produce(ThreadLocalRandom.current().nextInt(100, 1000));
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            producers[i].start();
        }

        try {
            Thread.sleep(6000);
            shutdown = true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

 

分享到:
评论

相关推荐

    后端开发基础知识整理JAVA、JVM、操作系统、网络、设计模式、mysql、redis、多线程、spring、springboo

    - **生产者消费者问题、哲学家就餐问题、读者写者问题**:经典的同步问题示例。 - **死锁的条件、排查、避免**:互斥条件、请求与保持条件、不剥夺条件、循环等待条件等。 - **互斥锁、自旋锁、读写锁、悲观锁、乐观...

    yolov8同时推理多路视频流,同时支持torch和onnx推理

    为了实现高效的并发,模型可能采用了多线程或多进程技术,将每一路视频流的处理独立开来,以充分利用多核处理器的优势。此外,模型可能会包含特定的同步策略,以确保在输出结果时不会发生冲突。 在实际应用中,...

    Java和J2EE的学习之路

    理解发布/订阅和点对点两种模式,以及消息生产者和消费者的使用,有助于构建高可用和解耦的应用系统。 在学习Java和J2EE的过程中,实践项目是非常重要的。通过参与或创建实际的Web应用,可以更好地理解和应用所学...

    java并发工具包 java.util.concurrent中文版-带书签版

    5. **阻塞队列(BlockingQueue)**:如`ArrayBlockingQueue`、`LinkedBlockingQueue`等,它们是线程安全的队列,支持等待插入(put)和等待取出(take)操作,常用于生产者消费者模型。 6. **CountDownLatch**:这...

    《Java十大经典案例》课件

    - **线程通信**:利用`wait()`, `notify()`, `notifyAll()`方法进行线程间的通信,实现生产者消费者模型。 - **线程池**:ExecutorService接口和ThreadPoolExecutor类用于管理线程池,提高系统性能并避免资源浪费...

    java经典面试题

    - 一种经典的多线程问题解决方案,涉及生产者线程和消费者线程。 25. **`ThreadLocal` 的设计理念与作用**: - 提供线程本地变量,避免数据共享带来的竞争条件。 26. **`ThreadPool` 用法与优势**: - 通过...

    java 1.7 官方中文

    2. **多路归并排序**:Java 1.7引入了`java.util.Arrays.sort()`的多路归并排序算法,提高了大规模数据的排序性能。 3. **类型推断(钻石操作符)**:在创建泛型实例时,可以省略类型参数,编译器会根据上下文自动...

    java开发项目管路

    在Java项目中,常见的设计模式如工厂模式、单例模式、观察者模式等,可以被用来解决特定问题,提高代码的可维护性和可扩展性。此外,MVC(模型-视图-控制器)架构是Web应用设计中的常见选择,它将业务逻辑、用户界面...

    Java面试知识点整理总结

    Java提供了丰富的并发工具,如线程、线程池、同步机制(synchronized,Lock),并发容器(如ConcurrentHashMap,CopyOnWriteArrayList),原子类(AtomicInteger,AtomicReference)以及并发编程模式(生产者消费者...

    Java高级架构师6期 视频教程 下载 因为太大 百度网盘链接3.zip

    │ 11 8-11 并发编程多线程调优(下) .mp4 │ ├─09 第九章 软件架构设计 │ 01 9-1 设计模式 (上).mp4 │ 02 9-2 设计模式 (下).mp4 │ 03 03 9-3 阿里系常用代码规范及工具-1.mp4 │ 03 03 9-3 阿里...

    重要基础知识.docx

    11. **阻塞队列与生产者-消费者模型**:阻塞队列在多线程间提供高效的数据传递,典型的生产者-消费者问题可以使用`BlockingQueue`实现。 12. **TCP的三次握手和四次挥手**:TCP连接建立需要三次握手,确保双方都能...

    java设计模式

    22.4.1 Java世界中的观察者模式 22.4.2 项目中真实观察者模式 22.4.3 订阅发布模型 22.5 最佳实践 第23章 门面模式 23.1 我要投递信件 23.2 门面模式的定义 23.3 门面模式的应用 23.3.1 门面模式的优点 23.3.2 门面...

    Java开发技术大全 电子版

    8.4.4生产者-消费者问题实例284 8.5本章小结287 第9章运行时类型识别288 9.1RTTI的作用288 9.2用Class类来加载对象289 9.3使用getClass()方法获取类信息290 9.4使用类标记292 9.5使用关键字instanceof判断...

    Java学习路线和规划

    8. **多线程编程** - **线程概念**:理解线程的基本概念和生命周期。 - **创建线程的方式**:通过继承Thread类或实现Runnable接口的方式来创建线程。 - **线程同步机制**:掌握`synchronized`关键字和Lock接口的...

    并发-线程池和阻塞队列.pdf

    例如,生产者-消费者问题就可以通过阻塞队列来优雅地解决。生产者在队列满时会被阻塞,直到队列有空间时再继续生产;消费者在队列空时也会被阻塞,直到队列中有元素时再继续消费。这种机制避免了传统的wait和notify...

    JUC并发编程学习笔记(硅谷)

    - `BlockingQueue`:阻塞队列,常用于生产者消费者模型,了解`ArrayBlockingQueue`、`LinkedBlockingQueue`等实现。 4. **并发工具** - `CountDownLatch`:一次性计数器,常用于多线程启动同步。 - `...

    2021面试指南(含各大简历模板)资料2.zip

    Kafka面试专题.docx可能涵盖Kafka的基本概念、架构、生产者消费者模型、消息持久化、高可用性及性能调优等内容。 4. **Spring Cloud与Docker实战微服务**:使用SpringCloud和Docker实战微服务.pdf可能探讨如何利用...

    面试篇大全.docx

    ### Java多线程面试题 1. **线程和进程的区别是什么?** - 进程是操作系统资源分配的基本单位,而线程是CPU调度和分派的基本单位。 - 一个进程可以有多个线程,线程之间共享进程内的资源,但每个线程有自己的执行...

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    云析学院-字节跳动2020第1季度面试题.pdf

    3. **阻塞队列**:在Java中,如`ArrayBlockingQueue`,是线程安全的数据结构,用于生产者-消费者模型,当队列满时,生产者会被阻塞,直到有空位;当队列空时,消费者会被阻塞,直到有元素。 4. **Redis与MongoDB的...

Global site tag (gtag.js) - Google Analytics