本文共 2773 字,大约阅读时间需要 9 分钟。
生产者消费者问题(Producer-consumer problem),也称为有限缓冲问题(Bounded-buffer problem),是一个经典的多线程同步问题。在Java面试中,这个问题经常被用来考察对多线程编程的理解。
生产者和消费者之间通过内存缓冲区进行通信。生产者生成数据并将其存储在缓冲区中,消费者则从缓冲区中读取数据进行处理。在实际运行中,生产者和消费者可能会面临缓冲区满或者空的情况,这需要通过同步机制来处理。
以下是一个简单的Java实现,使用synchronized方法和wait/notify机制来实现生产者和消费者之间的协调。
public class Resources { private int[] arr = new int[5]; private int count = 0; public synchronized void product() { if (count == arr.length) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { int m = (int) (Math.random() * 10 + 1); arr[count] = m; count++; System.out.println("生产:" + m); notify(); } } public synchronized void consume() { if (count == 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { int n = arr[count - 1]; arr[count - 1] = 0; count--; System.out.println("消费:" + n); notify(); } }}public class ProduceThread extends Thread { private Resources r; public ProduceThread(Resources r) { this.r = r; } public void run() { try { while (true) { r.product(); Thread.sleep(1); } } catch (Exception e) { e.printStackTrace(); } }}public class ConsumerThread extends Thread { private Resources r; public ConsumerThread(Resources r) { this.r = r; } public void run() { try { while (true) { r.consume(); Thread.sleep(1); } } catch (Exception e) { e.printStackTrace(); } }}public class Test { public static void main(String[] args) { Resources r = new Resources(); ProduceThread t1 = new ProduceThread(r); ConsumerThread t2 = new ConsumerThread(r); t1.start(); t2.start(); }} 运行上述代码,可以在控制台看到如下输出:
生产:4消费:4生产:7消费:7生产:8生产:4消费:4消费:8生产:4消费:4生产:2消费:2生产:8消费:5消费:8生产:3消费:1...
Java提供的锁是对象级的:每个对象都有自己的锁,而不是线程级的锁。生产者和消费者通过共享同一个资源对象来获取锁。
wait()方法的作用:wait()方法会让当前线程暂停,直到另一个线程通过notify()或notifyAll()方法唤醒它。
notify()与notifyAll()的区别:
在Java中,每个对象都有一把锁。线程可以通过synchronized关键字获取对象锁,并在方法执行期间自动释放锁。这样可以防止多个线程同时操作共享资源,避免数据不一致和竞争。
共同点:都能唤醒正在等待的线程,并且在唤醒后,只有一个线程能获取对象锁。
区别:
生产者消费者问题是Java多线程编程中的经典问题。通过synchronized方法和wait/notify机制,可以实现生产者和消费者之间的协调。在实际应用中,可以根据具体需求选择适合的同步机制来确保线程安全和系统稳定性。
转载地址:http://dwjv.baihongyu.com/