方法/ 作用
wait: 线程自动释放占有的对象锁,并等待notify。
notify: 随机唤醒一个正在wait当前对象的线程,并让被唤醒的线程拿到对象锁
notifyAll: 唤醒所有正在wait当前对象的线程,但是被唤醒的线程会再次去竞争对象锁。因为一次只有一个线程能拿到锁,所有其他没有拿到锁的线程会被阻塞。推荐使用。
Java中规定,在调用这三个方法时,当前线程必须获得对象锁。因此就得配合synchronized关键字来使用。在synchronized拿到对象锁之后,synchronized代码块或者方法中,必定是会持有对象锁的,因此就可以使用wait()或者notify()。
使用wait()、notify()来实现一个生产者、消费者模式:
class ProductAndCusumer {
private static final Integer MAX_CAPACITY = 5;
private static LinkedList<String> queue = new LinkedList<>(); //需要将queue作为多线程操作的锁
static class Producter extends Thread {
@Override
public void run() {
while (true) {
synchronized (queue) {
if (queue.size() >= MAX_CAPACITY * 2) {
System.out.println("缓冲队列已满");
//停止生产产品,此时在生产者的线程中,调用queue.wait主动去释放锁,
//让当前消费线程进入等待唤醒去拿锁
try {
queue.wait();
} catch (Exception e) {
}
}
//没有满,继续生产
String product = "生产:" + Thread.currentThread().getName();
System.out.println(product);
queue.add(product);
try {
Thread.sleep(500);
} catch (Exception e) {
}
try {
queue.notifyAll(); //唤醒所有线程拿锁
} catch (Exception e) {
}
}
}
}
}
static class Consumer extends Thread {
@Override
public void run() {
while (true) {
synchronized (queue) {
if (queue.isEmpty()) {
System.out.println("缓冲队列为空,暂无消费产品");
try {
queue.wait();
} catch (Exception e) {
}
}
try {
System.out.println("消费:" + queue.pop());
Thread.sleep(500);
queue.notifyAll();
} catch (Exception e) {
}
}
}
}
}
public static void main(String[] args) {
new Producter().start();
new Consumer().start();
}
}
网友评论