一、Thread.wait()和notify()实现生产者消费者
Thread的wait()方法阻塞线程,notify()方法唤醒线程。
Producer模拟产者线程生产并保存到仓库,如果仓库满了,线程阻塞等待......
public class Producer implements Runnable {
private int size;
private Queue<String> products;
public Producer(int size, Queue<String> products) {
this.size = size;
this.products = products;
}
@Override
public void run() {
int i = 0;
while (true) {
i++;
synchronized (products) {
while (products.size() == size) {
System.out.println("仓库已满,无法再继续生产products...");
try {
products.wait(); //阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产者生产了一个product"+i);
products.add("product" + i);
products.notify(); //唤醒消费者消费
}
}
}
}
Consumer模拟消费者线程消费仓库中的产品,如果仓库空了,线程阻塞等待......
public class Consumer implements Runnable {
private int size;
private Queue<String> products;
public Consumer(int size, Queue<String> products) {
this.size = size;
this.products = products;
}
@Override
public void run() {
while (true) {
synchronized (products) {
while (products.size() == 0) {
System.out.println("仓库是空的...");
try {
products.wait(); //阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String product = products.remove();
System.out.println("消费者消费了一个" + product);
products.notify(); //唤醒生产者生产
}
}
}
}
主线程:启动生产者线程开始生产、消费者线程开始消费
public class WaitNotifyDemo {
public static void main(String[] args) {
int size = 10;
Queue<String> queue = new LinkedList<String>();
Producer producer = new Producer(size, queue);
Consumer consumer = new Consumer(size, queue);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start(); //生产者线程启动
thread2.start(); //消费者线程启动
}
}
输出结果如下:
生产者生产了一个product1
生产者生产了一个product2
生产者生产了一个product3
生产者生产了一个product4
消费者消费了一个product1
消费者消费了一个product2
消费者消费了一个product3
生产者生产了一个product5
生产者生产了一个product6
生产者生产了一个product7
生产者生产了一个product8
生产者生产了一个product9
生产者生产了一个product10
生产者生产了一个product11
生产者生产了一个product12
生产者生产了一个product13
仓库已满,无法再继续生产products...
消费者消费了一个product4
生产者生产了一个product14
消费者消费了一个product5
消费者消费了一个product6
消费者消费了一个product7
消费者消费了一个product8
消费者消费了一个product9
生产者生产了一个product15
消费者消费了一个product10
消费者消费了一个product11
消费者消费了一个product12
消费者消费了一个product13
消费者消费了一个product14
消费者消费了一个product15
生产者生产了一个product16
消费者消费了一个product16
仓库是空的...
生产者生产了一个product17
生产者生产了一个product18
生产者生产了一个product19
生产者生产了一个product20
生产者生产了一个product21
生产者生产了一个product22
...
注意:在使用wait()和notify()方法时都需要加上synchronized关键字,因为线程之间通信需要一个载体,synchronized就是这个通信载体;其次wait()和notify()方法互斥,每次执行时需要竞争获取锁,通过synchronized来锁着对象,从而实现让wait()和notify()方法无法同时对队列进行操作。