生产者消费者模型是一种常用的线程同步模型,它通过在多个线程之间协调共享资源的访问,来提高系统的效率和可靠性。在生产者消费者模型中,生产者线程负责生成数据,消费者线程负责消费数据,两者通过共享队列来协作,实现生产与消费
JAVA生产者消费者(线程同步)代码学习示例
什么是生产者消费者模型
生产者消费者模型是一种常用的线程同步模型,它通过在多个线程之间协调共享资源的访问,来提高系统的效率和可靠性。在生产者消费者模型中,生产者线程负责生成数据,消费者线程负责消费数据,两者通过共享队列来协作,实现生产与消费的同步和协调。
学习示例1:基本实现
假设有一个生产者线程和一个消费者线程共享一个阻塞队列,生产者线程每次在队列尾部添加一个数字,消费者线程每次从队列头部获取一个数字,并将它打印出来。代码如下:
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumerExample {
private Queue<Integer> queue = new LinkedList<>();
private static final int MAX_SIZE = 10;
public static void main(String[] args) throws InterruptedException {
ProducerConsumerExample example = new ProducerConsumerExample();
Thread producerThread = new Thread(() -> {
for (int i = 1; i <= 20; i++) {
try {
example.produce(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumerThread = new Thread(() -> {
for (int i = 1; i <= 20; i++) {
try {
example.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producerThread.start();
consumerThread.start();
producerThread.join();
consumerThread.join();
}
public synchronized void produce(int value) throws InterruptedException {
while (queue.size() == MAX_SIZE) {
wait();
}
queue.offer(value);
System.out.println("生产者生产了:" + value);
notifyAll();
}
public synchronized void consume() throws InterruptedException {
while (queue.isEmpty()) {
wait();
}
int value = queue.poll();
System.out.println("消费者消费了:" + value);
notifyAll();
}
}
在上面的示例中,我们使用了 synchronized 关键字来实现线程同步。在 produce() 和 consume() 方法中,每次都通过 synchronized 关键字来获取对象锁,以确保线程安全。同时,在队列满或队列空的情况下,我们使用了 wait() 方法来让当前线程进入等待状态,直到条件得到满足。
学习示例2:更高效的实现
在示例1中,我们使用了 synchronized 和 wait() 这些关键字来实现线程同步。但是,在高并发情况下,这些关键字会导致性能问题,因为每次获取锁和释放锁都会有一定的开销。因此,我们可以通过使用 java.util.concurrent 包中提供的并发工具来优化生产者消费者模型的实现。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ProducerConsumerExample2 {
private BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
private static final int MAX_SIZE = 10;
public static void main(String[] args) throws InterruptedException {
ProducerConsumerExample2 example = new ProducerConsumerExample2();
Thread producerThread = new Thread(() -> {
for (int i = 1; i <= 20; i++) {
try {
example.produce(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumerThread = new Thread(() -> {
for (int i = 1; i <= 20; i++) {
try {
example.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producerThread.start();
consumerThread.start();
producerThread.join();
consumerThread.join();
}
public void produce(int value) throws InterruptedException {
queue.put(value);
System.out.println("生产者生产了:" + value);
}
public void consume() throws InterruptedException {
int value = queue.take();
System.out.println("消费者消费了:" + value);
}
}
在上面的示例中,我们使用了 java.util.concurrent 包中提供的 BlockingQueue 接口来实现线程同步。BlockingQueue 接口可以自动实现线程同步和阻塞队列的功能,从而简化了代码的实现。在生产者线程中,我们使用 put() 方法来向队列尾部添加元素;在消费者线程中,我们使用 take() 方法来从队列头部获取元素。在队列已满或队列为空的情况下,put() 和 take() 方法会自动阻塞,直到条件得到满足。这样可以避免了使用 wait() 和 notify() 导致的性能问题。
总结
生产者消费者模型是一种常用的线程同步模型,它通过在多个线程之间协调共享资源的访问,来提高系统的效率和可靠性。在示例1中,我们使用了 synchronized 和 wait() 这些关键字来实现线程同步;在示例2中,我们使用了 java.util.concurrent 包中提供的 BlockingQueue 接口来简化代码实现,并提高了程序的并发性能。
本文标题为:JAVA生产者消费者(线程同步)代码学习示例
基础教程推荐
- java利用easyexcel实现导入与导出功能 2023-05-24
- Springboot 中的 Filter 实现超大响应 JSON 数据压缩的方法 2023-06-10
- Java CompletableFuture实现原理分析详解 2023-06-05
- 在jsp页面如何获得url参数 2023-12-16
- Java语言中flush()函数作用及使用方法详解 2024-01-07
- 在MySql Java中获取2天之间的所有数据 2023-10-30
- 深入解析Java编程中方法的参数传递 2024-01-07
- SpringBoot项目中建议关闭Open-EntityManager-in-view原因 2022-11-03
- Java Date(日期)对象进行格式化的思路详解 2023-05-18
- $.ajax()方法进行网页间传值示例 2023-12-17
