wait()和notify()
wait()和notify()的方法并不是线程对象专属的方法,Java中所有的对象都有这两个方法。
object.wait(): 持有obj对象锁的当前线程进入等待状态,并释放该对象的锁。
object.notify(): 唤醒之前进入等待状态的线程,使这些线程重新尝试获取对象锁。
模拟生产者和消费者模式
仓库,生产者,消费者三者之间,常常达到供需平衡的状态,即:
生产者生产指定量的产品,便不能生产(wait),需要通知消费者进行消费(notify);
消费者消费完所有库存,便不能再消费(wait),需要告知生产者进行生产(notify)。
如下代码模拟以上模式:
import java.util.ArrayList;
import java.util.List;
public class ConsumerAndProducerTest {
public static void main(String[] args) {
// 模拟仓库
List<Integer> list = new ArrayList<>();
// 创建生产者线程
Thread producer = new Thread(new Producer(list), "生产者");
// 创建消费者线程
Thread consumer = new Thread(new Consumer(list), "消费者");
// 同时启动生产者和消费着
producer.start();
consumer.start();
}
}
/**
* 消费者类
*/
class Consumer implements Runnable {
final List<Integer> list;
int number = 0;
public Consumer(List<Integer> list) {
this.list = list;
}
@Override
public void run() {
synchronized (list) {
while (true) {
// 判断仓库中商品是否空了
if (list.size() == 0) {
try {
list.wait(); // 没有商品,进入等待状态并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费库存中第一件商品,并返回商品编号
int id = list.remove(0);
System.out.println(Thread.currentThread().getName() + "消费了商品" + id + String.format(",已消费%d件商品!", ++number));
// 唤醒其他线程
list.notifyAll();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 生产者类
*/
class Producer implements Runnable {
final List<Integer> list;
int id = 0;
public Producer(List<Integer> list) {
this.list = list;
}
@Override
public void run() {
synchronized (list) {
while (true) {
// 判断仓库中商品是否有指定数量库存
if (list.size() >= 2) {
try {
list.wait(); // 有商品,进入等待状态并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 生产
list.add(++id);
System.out.println(Thread.currentThread().getName() + "生产了商品" + id + String.format(", 现仓库有%d件未售出!", list.size()));
// 唤醒其他线程
list.notifyAll();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
网友评论