生产者消费者模型是一种常用的线程同步模型,它通过在多个线程之间协调共享资源的访问,来提高系统的效率和可靠性。在生产者消费者模型中,生产者线程负责生成数据,消费者线程负责消费数据,两者通过共享队列来协作,实现生产与消费
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生产者消费者(线程同步)代码学习示例
基础教程推荐
- Log4j关闭Spring和Hibernate日志打印方式 2023-08-07
- springboot themaleaf 第一次进页面不加载css的问题 2023-06-24
- JSP Session超时设置的实现方法 2023-07-31
- Java获取环境变量(System.getenv)的方法 2022-11-07
- 用法介绍Java HelloWorld程序 2023-10-08
- Springboot 集成spring cache缓存的解决方案 2022-11-29
- Java8简单了解Lambda表达式与函数式接口 2024-03-08
- 一文搞懂java中类及static关键字执行顺序 2023-05-08
- Java实现删除排序数组中重复元素的方法小结【三种方法比较】 2024-03-01
- 一分钟掌握Java ElasticJob分布式定时任务 2023-07-14