一、wait(),notify(),notifyAll(),join()?
wait()在当前获取的锁对象上调用,调用后释放获得的锁,线程进入waiting状态。(在哪个线程调用,哪个线程等待)
notify()在当前获取的锁对象上调用,唤醒一个在锁等待的线程,线程进入Block状态
notify()唤醒所有在当前锁等待的线程,线程进入Block状态
join()对线程实例调用后,等该线程结束时才会继续执行后续代码
二、代码示例及源码阅读
1.示例
代码如下:
public class Test extends Thread{
public static void main(String[] args) throws InterruptedException{
Test t = new Test();
Thread tt = new Thread(()->{
t.start();
try {
Thread.sleep(10);
System.out.println("线程状态:"+t.getState());
t.notifyTest();
System.out.println("线程状态:"+t.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
tt.start();
tt.join();
}
@Override
public synchronized void run() {
int i = 1;
while (i<3){
System.out.println(this.getName()+":打印"+i);
i++;
}
try {
this.wait();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void notifyTest(){
this.notifyAll();
}
}
运行结果:
Thread-0:打印1
Thread-0:打印2
线程状态:WAITING
线程状态:BLOCKED
2.源码阅读
代码如下:
//wait()、notify()、notifyAll()为本地方法
public final void wait() throws InterruptedException {
wait(0);
}
public final native void notify();
public final native void notifyAll();
//重点关注join()方法,调用重载方法join(0)
public final void join() throws InterruptedException {
join(0);
}
/**
* 等待至多指定时间,如果为0,则等待直至线程结束
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}.
* 当线程结束时自动调用notifyAll()方法唤醒此线程
* As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
//使用循环判断,当线程未结束时被唤醒继续等待,线程未开始时直接跳过
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
总结
如有错漏,敬请指出。