JAVA生产者消费者(线程同步)代码学习示例

生产者消费者模型是一种常用的线程同步模型,它通过在多个线程之间协调共享资源的访问,来提高系统的效率和可靠性。在生产者消费者模型中,生产者线程负责生成数据,消费者线程负责消费数据,两者通过共享队列来协作,实现生产与消费

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中,我们使用了 synchronizedwait() 这些关键字来实现线程同步。但是,在高并发情况下,这些关键字会导致性能问题,因为每次获取锁和释放锁都会有一定的开销。因此,我们可以通过使用 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中,我们使用了 synchronizedwait() 这些关键字来实现线程同步;在示例2中,我们使用了 java.util.concurrent 包中提供的 BlockingQueue 接口来简化代码实现,并提高了程序的并发性能。

本文标题为:JAVA生产者消费者(线程同步)代码学习示例

基础教程推荐