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和J2EE的过程中,实践项目是非常重要的。通过参与或创建实际的Web应用,可以更好地理解和应用所学...
5. **阻塞队列(BlockingQueue)**:如`ArrayBlockingQueue`、`LinkedBlockingQueue`等,它们是线程安全的队列,支持等待插入(put)和等待取出(take)操作,常用于生产者消费者模型。 6. **CountDownLatch**:这...
- **线程通信**:利用`wait()`, `notify()`, `notifyAll()`方法进行线程间的通信,实现生产者消费者模型。 - **线程池**:ExecutorService接口和ThreadPoolExecutor类用于管理线程池,提高系统性能并避免资源浪费...
- 一种经典的多线程问题解决方案,涉及生产者线程和消费者线程。 25. **`ThreadLocal` 的设计理念与作用**: - 提供线程本地变量,避免数据共享带来的竞争条件。 26. **`ThreadPool` 用法与优势**: - 通过...
2. **多路归并排序**:Java 1.7引入了`java.util.Arrays.sort()`的多路归并排序算法,提高了大规模数据的排序性能。 3. **类型推断(钻石操作符)**:在创建泛型实例时,可以省略类型参数,编译器会根据上下文自动...
在Java项目中,常见的设计模式如工厂模式、单例模式、观察者模式等,可以被用来解决特定问题,提高代码的可维护性和可扩展性。此外,MVC(模型-视图-控制器)架构是Web应用设计中的常见选择,它将业务逻辑、用户界面...
Java提供了丰富的并发工具,如线程、线程池、同步机制(synchronized,Lock),并发容器(如ConcurrentHashMap,CopyOnWriteArrayList),原子类(AtomicInteger,AtomicReference)以及并发编程模式(生产者消费者...
│ 11 8-11 并发编程多线程调优(下) .mp4 │ ├─09 第九章 软件架构设计 │ 01 9-1 设计模式 (上).mp4 │ 02 9-2 设计模式 (下).mp4 │ 03 03 9-3 阿里系常用代码规范及工具-1.mp4 │ 03 03 9-3 阿里...
11. **阻塞队列与生产者-消费者模型**:阻塞队列在多线程间提供高效的数据传递,典型的生产者-消费者问题可以使用`BlockingQueue`实现。 12. **TCP的三次握手和四次挥手**:TCP连接建立需要三次握手,确保双方都能...
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 门面...
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判断...
8. **多线程编程** - **线程概念**:理解线程的基本概念和生命周期。 - **创建线程的方式**:通过继承Thread类或实现Runnable接口的方式来创建线程。 - **线程同步机制**:掌握`synchronized`关键字和Lock接口的...
例如,生产者-消费者问题就可以通过阻塞队列来优雅地解决。生产者在队列满时会被阻塞,直到队列有空间时再继续生产;消费者在队列空时也会被阻塞,直到队列中有元素时再继续消费。这种机制避免了传统的wait和notify...
- `BlockingQueue`:阻塞队列,常用于生产者消费者模型,了解`ArrayBlockingQueue`、`LinkedBlockingQueue`等实现。 4. **并发工具** - `CountDownLatch`:一次性计数器,常用于多线程启动同步。 - `...
Kafka面试专题.docx可能涵盖Kafka的基本概念、架构、生产者消费者模型、消息持久化、高可用性及性能调优等内容。 4. **Spring Cloud与Docker实战微服务**:使用SpringCloud和Docker实战微服务.pdf可能探讨如何利用...
### Java多线程面试题 1. **线程和进程的区别是什么?** - 进程是操作系统资源分配的基本单位,而线程是CPU调度和分派的基本单位。 - 一个进程可以有多个线程,线程之间共享进程内的资源,但每个线程有自己的执行...
25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................
3. **阻塞队列**:在Java中,如`ArrayBlockingQueue`,是线程安全的数据结构,用于生产者-消费者模型,当队列满时,生产者会被阻塞,直到有空位;当队列空时,消费者会被阻塞,直到有元素。 4. **Redis与MongoDB的...