Java线程生产者消费者模型是一种常见的多线程应用模型,它可以有效地利用多核CPU的优势,提高系统的性能。它的基本原理是:生产者将数据产生出来,然后将其放入一个共享内存中;而消费者从共享内存中取出数据进行处理。
Java中实现生产者-消费者模式有很多方法,但是最常用的方法就是使用wait()、notify()和notifyAll()三个方法。wait()方法使当前执行代码的线程进入阻塞(blocked)状态;notify()方法唤醒正在阻塞中的一个线程;notifyAll()方法则可以唤醒所有正在阻塞中的多个线程。
public class ProducerConsumer { private static int count = 0; public static void main(String[] args) { // 创建一个对象作为同步锁 Object lock = new Object(); // 创建生产者对象 Producer producer = new Producer(lock); // 创建消费者对象 Consumer consumer = new Consumer(lock); // 启动生产者、消费者进行工作 producer.start(); consumer.start(); } static class Producer extends Thread { private Object lock; public Producer(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { while (true) { if (count == 0) { System.out.println("Producer: " + ++count); lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) {} } } } } } static class Consumer extends Thread { private Object lock; public Consumer(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { while (true) { if (count != 0) { System.out.println("Consumer: " + count--); lock.notify(); } else { try{ lock.wait(); } catch (InterruptedException e){} } } } }}
生产者/消费者是使用wait()和notify()方法的典型线程同步问题。
有四个类:缓冲区,生产者,消费者和生产者CumerumerTest。
Buffer类的一个对象具有一个整数数据元素,它将由生产者生成并由消费者消费。
我们必须同步对缓冲区的访问,因此只有当缓冲区为空时,生产者才产生一个新的数据元素,而消费者只有在可用时才消耗缓冲区的数据。
ProducerConsumerTest类用于测试程序。
import java.util.Random; class Consumer extends Thread { private Buffer buffer; public Consumer(Buffer buffer) { this.buffer = buffer; } public void run() { int data; while (true) { data = buffer.consume(); } } } public class Main { public static void main(String[] args) { Buffer buffer = new Buffer(); Producer p = new Producer(buffer); Consumer c = new Consumer(buffer); p.start(); c.start(); } } class Producer extends Thread { private Buffer buffer; public Producer(Buffer buffer) { this.buffer = buffer; } public void run() { Random rand = new Random(); while (true) { int n = rand.nextInt(); buffer.produce(n); } } } class Buffer { private int data; private boolean empty; public Buffer() { this.empty = true; } public synchronized void produce(int newData) { while (!this.empty) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.data = newData; this.empty = false; this.notify(); System.out.println("Produced:" + newData); } public synchronized int consume() { while (this.empty) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.empty = true; this.notify(); System.out.println("Consumed:" + data); return data; } }
上面的代码生成以下结果。
Java线程教程 -Java Volatile变量关键字volatile可以保持线程的工作内存中的变量值与它们在主存储器中的值同步。我们可以声明一...
Java线程教程 -Java线程生命周期线程总是处于以下六种状态之一:NewRunnableBlockedWaitingTimed-waitingTerminated线程的所有这...
Java线程教程 -Java同步器同步器对象与一组线程一起使用。它维护一个状态,根据它的状态,它让一个线程通过或强迫它等待。本节将...
Java网络教程 -Java URL绝对URI具有以下通用格式:scheme:scheme-specific-part scheme-specific-part 取决于 scheme 。例如,ht...