一、notify和notifyAll方法的作用
Java中的notify和notifyAll方法是用于线程间通信的机制。在多个线程共同竞争一个锁对象时,当该锁对象被其中一个线程占用时,其他线程需要等待,直到占用该锁对象的线程释放锁。而notify和notifyAll方法可以用来通知其他线程,告知它们可以再次竞争锁对象了。
二、notify和notifyAll方法的区别
notify方法会随机选择一个正在等待该锁对象的线程进行唤醒,而notifyAll方法会唤醒所有正在等待该锁对象的线程。
public class TestNotify {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(new WaitThread(), "wait-thread-1");
Thread thread2 = new Thread(new WaitThread(), "wait-thread-2");
Thread thread3 = new Thread(new NotifyThread(), "notify-thread");
thread1.start();
thread2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread3.start();
}
static class WaitThread implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " enter synchronized block");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " leave synchronized block");
}
}
}
static class NotifyThread implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " enter synchronized block");
lock.notifyAll();
System.out.println(Thread.currentThread().getName() + " leave synchronized block");
}
}
}
}
三、notify和notifyAll方法的使用场景
在实际应用中,notify和notifyAll方法一般用于生产者消费者模型中,用来唤醒等待队列中的消费者线程。在生产者消费者模型中,当生产者向队列中放入数据时,如果队列已经满了,就需要唤醒正在等待的消费者线程;当消费者从队列中取出数据时,如果队列已经空了,就需要唤醒正在等待的生产者线程。
public class WaitNotifyExample {
public static void main(String[] args) {
Queue queue = new PriorityQueue();
Thread producer = new Thread(() -> {
for (int i = 0; i {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int number = queue.poll();
System.out.println("Consumer: " + number);
queue.notifyAll();
}
}
});
producer.start();
consumer.start();
}
}
四、notify和notifyAll方法的注意事项
在使用notify和notifyAll方法时,需要注意以下事项:
1. 必须在同步块中调用notify和notifyAll方法,否则会抛出IllegalMonitorStateException异常;
2. 如果使用notify方法,则在多线程竞争锁时并不能保证哪个线程会收到通知,因此一般使用notifyAll方法;
3. notify和notifyAll方法并不是真正释放锁,只是唤醒等待队列中的线程,当前线程还需要执行完同步块才会释放锁。
原创文章,作者:NKSD,如若转载,请注明出处:https://www.506064.com/n/147728.html
微信扫一扫
支付宝扫一扫