生产模式 + 消费模式
重点:测试 Object 类的
wait
方法和notify
方法
代码:
import java.util.ArrayList;
import java.util.List;
/**
* 使用 wait 和 notify 方法实现 “生产者和消费者模式”
* 两个线程共享一个仓库,用 List 集合模拟仓库
* 假设 List 集合中只能存储 1 个元素,1 个元素仓库就满了,0 个元素仓库就空了
*
* 效果:生成 1 个,消费 1 个
*/
public class ThreadTest12 {
public static void main(String[] args) {
// 创建一个共享的仓库对象
List li = new ArrayList();
// 创建两个线程
Thread t1 = new Thread(new Producer(li));
Thread t2 = new Thread(new Consumer(li));
t1.setName("生产者线程");
t2.setName("消费者线程");
t1.start();
t2.start();
}
}
// 生产线程
class Producer implements Runnable{
// 仓库
private List list; // 面向接口编程
public Producer(List list){
this.list = list;
}
@Override
public void run() {
// 一直生产(死循环)
while (true){
// 给仓库对象加锁
synchronized (list){
// 仓库容量大于0,仓库满了
if (list.size() == 1){
try {
// 不能生产了
// 生产线程/当前线程进入等待状态,释放占有的仓库(List集合)对象锁
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// int i = 0;
// 仓库是空的,可以进行生产
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName() + "生产了--->" + obj);
// i++;
// 到这里需要唤醒消费程进行消费
// if (i == 10){
list.notify(); // 不会释放锁
// }
// list.notifyAll(); 也可以
}
}
}
}
// 消费线程
class Consumer implements Runnable{
private List list;
public Consumer(List list){
this.list = list;
}
@Override
public void run() {
// 一直消费
while (true){
synchronized (list){
// 仓库空了
if (list.size() == 0){
try {
// 不能消费了
// 消费者线程等待,释放占有的仓库(List集合)对象锁
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 程序到此说明仓库有东西,可以进行消费,所以开始消费
// for (int i = 0; i < list.size(); i++) {
// Object o = list.get(i);
// Object o = list.remove(i);
System.out.println(Thread.currentThread().getName() + "消费--->" + list.remove(0));
// }
// Object o = list.remove(0);
// System.out.println(Thread.currentThread().getName() + "消费了--->" + o);
// 到这里唤醒生成线程进行生产
list.notify(); // 不会释放锁
// list.notifyAll(); 也可以
}
}
}
}
运行结果:
消费者线程消费--->java.lang.Object@6663d9d6
生产者线程生产了--->java.lang.Object@6f9e92b2
消费者线程消费--->java.lang.Object@6f9e92b2
生产者线程生产了--->java.lang.Object@4d5d3f6a
消费者线程消费--->java.lang.Object@4d5d3f6a
生产者线程生产了--->java.lang.Object@21969daf
消费者线程消费--->java.lang.Object@21969daf
生产者线程生产了--->java.lang.Object@59c34d22
消费者线程消费--->java.lang.Object@59c34d22
生产者线程生产了--->java.lang.Object@42d34faa
消费者线程消费--->java.lang.Object@42d34faa
生产者线程生产了--->java.lang.Object@66d18ef5
消费者线程消费--->java.lang.Object@66d18ef5
生产者线程生产了--->java.lang.Object@73bf0c65
消费者线程消费--->java.lang.Object@73bf0c65
生产者线程生产了--->java.lang.Object@3056e56d
消费者线程消费--->java.lang.Object@3056e56d
PS:这是一个死循环的输出,以上结果是部分结果的示例