要求:生产一个消费一个。
调用wait()方法会让“当前线程”进入等待状态。
调用notify()方法可以唤醒处于等待的线程。
调用notify()方法可以唤醒处于等待的所有线程。
wait()和notify()方法并不是线程对象的方法, 而是任何一个java对象自带的方法。
synchronized 关键字表示同步的,按照我的理解就是上锁,锁住共享对象,在生产者和消费者模式中,创建的仓库就是共享对象。
首先创建两个线程,一是生产者线程,二是消费者线程;两个线程共享仓库。在生产线程中,首先使用synchronized关键字上锁,判断仓库里面是否有数据,如果有数据,生产线程就使用wait()方法使当前生产线程进入等待状态,并且释放生产者之前占有的共享对现象锁。此时已经将锁释放了,则另外一个消费者线程拿到锁,这个时候已知道仓库里面有数据,则直接进行消费并通知生产者进行进行生产。如果没有数据,生产者就生产数据,生产线程生产完数据并通知消费者进行消费,该线程结束,释放了锁;消费者拿到锁之后,进行判断,发现没有数据,则使用wait()方法,让消费者线程等待,并释放掉共享对象的锁。
package java.thread;
import java.util.ArrayList;
import java.util.List;
public class ThreadTest16 {
public static void main(String[] args) {
// 创建仓库共享对象
List list = new ArrayList();
// 创建两个线程对象
// 生产者线程
Thread t1 = new Thread(new Producer(list));
// 消费者线程
Thread t2 = new Thread(new Consumer(list));
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) {
if (list.size() > 0) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 说明仓库是空的,可以生产
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName() + "--->" + obj);
// 唤醒消费者进行消费
list.notify();
}
}
}
}
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){
// 消费者线程等待,释放掉list集合的锁。
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 说明仓库有数据,可以进行消费
Object obj = list.remove(0);
System.out.println(Thread.currentThread().getName() + "--->" + obj);
// 唤醒生产者生产。
list.notify();
}
}
}
}