三个方法:
- wait(): 一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器(锁)。
- notify(): 一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
- notifyAll(): 一旦执行此方法,就会唤醒所有被wait的线程。
说明:
- wait()、notify()、notifyAll()三个方法必须使用在同步代码块或者同步方法中。
- wait()、notify()、notifyAll()三个方法的调用者必须是同步代码块或者同步方法中的同步监视器,否则会出现IllegalMonitorStateException异常。
- wait()、notify()、notifyAll()三个方法是定义在java.lang.Object类中。
public class ProductTest {
public static void main(String[] args) {
Clerk clerk = new Clerk();
Producer p1 = new Producer(clerk);
Thread t1 = new Thread(p1);
t1.setName("生产者");
Customer c1 = new Customer(clerk);
Thread t2 = new Thread(c1);
t2.setName("消费者1");
Thread t3 = new Thread(c1);
t3.setName("消费者2");
t1.start();
t2.start();
t3.start();
}
}
class Clerk {//店员类
//共享的数据:产品
private int number = 0;
//生产产品
public synchronized void produceProduct() {
if (number < 20){
number ++;
System.out.println(Thread.currentThread().getName() + "开始生产第" + number + "个产品");
notify(); //一生产就唤醒消费者去消费
} else {
//等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//消费产品
public synchronized void consumeProduct() {
if (number > 0){
System.out.println(Thread.currentThread().getName() + "开始消费第" + number + "个产品");
number --;
notify(); //一消费就唤醒生产者去生产
} else {
//等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer implements Runnable{ //生产者
private Clerk clerk;
public Producer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始生产产品");
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.produceProduct();
}
}
}
class Customer implements Runnable{ //消费者
private Clerk clerk;
public Customer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始消费产品");
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.consumeProduct();
}
}
}