Laughing
Java线程间的通信之等待/通知机制
06/06
本文最后更新于2024年03月18日,已超过186天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!
上⾯⼀种基于“锁”的⽅式,线程需要不断地去尝试获得锁,如果失败了,再继续尝试。这可能会耗费服务器资源。⽽等待/通知机制是另⼀种⽅式。Java
多线程的等待/通知机制是基于Object
类的wait()
⽅法和notify()
,notifyAll()
⽅法来实现的。
notify()⽅法会随机叫醒⼀个正在等待的线程,⽽notifyAll()会叫醒所有正在等待的线程。
前⾯我们讲到,⼀个锁同⼀时刻只能被⼀个线程持有。⽽假如线程A现在持有了⼀个锁
lock
并开始执⾏,它可以使⽤lock.wait()
让⾃⼰进⼊等待状态。这个时候,lock
这个锁是被释放了的。这时,线程B获得了lock
这个锁并开始执⾏,它可以在某⼀时刻,使⽤
lock.notify()
,通知之前持有lock
锁并进⼊等待状态的线程A,说“线程A你不⽤等了,可以往下执⾏了”。需要注意的是,这个时候线程B并没有释放锁
lock
,除⾮线程B这个时候使⽤lock.wait()
释放锁,或者线程B执⾏结束⾃⾏释放锁,线程A才能得到lock
锁。package com.company;
import java.util.stream.IntStream;
public class WaitAndNotify {
private static Object lock = new Object();
static class ThreadA implements Runnable{
@Override
public void run() {
synchronized (lock){
IntStream.range(1,5).forEach(i->{
System.out.println("ThreadA:"+i);
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
static class ThreadB implements Runnable{
@Override
public void run() {
synchronized (lock){
IntStream.range(1,5).forEach(i->{
System.out.println("ThreadB:"+i);
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new ThreadA()).start();
Thread.sleep(1000);
new Thread(new ThreadB()).start();
}
}
需要注意的是等待/通知机制使⽤的是使⽤同⼀个对象锁,如果你两个线程使⽤的是不同的对象锁,那它们之间是不能⽤等待/通知机制通信的。
版权属于:
香草物语
本文链接:
https://www.xiangcaowuyu.net/java/waiting-notification-mechanism-of-communication-between-java-threads.html(转载时请注明本文出处及文章链接)
作品采用:
感谢分享