Java架构师交流群:793825326
java版本:jdk1.8
IDE:idea 18
这三个关键子一般配合synchronized,不然会报java.lang.IllegalMonitorStateException异常。看下面的代码:
public class Test {
public synchronized void start() {
try {
System.out.println(Thread.currentThread().getId() + "执行");
this.wait();
System.out.println(Thread.currentThread().getId() + "start");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getId() + "end");
} catch (Exception ex) {
System.out.println(ex);
}
}
public synchronized void releaseAll()
{
this.notifyAll();
}
public synchronized void releaseOne()
{
this.notify();
}
}
测试代码:
Test t=new Test();
try {
Thread thread1= new Thread(() -> t.start());
thread1.start();
Thread.sleep(100);
Thread thread2= new Thread(() -> t.start());
thread2.start();
Thread.sleep(1000);
t.releaseAll();
}
catch (Exception ex)
{
System.out.println(ex);
}
执行结果如下:
14执行
15执行
15start
15end
14start
14end
也就是说,当程序执行到wait方法后,会释放synchronized锁,阻塞等待。当其他线程调用notifyAll(),所有正在等待的线程开始尝试重新获取synchronized锁,谁先获取到锁,则谁可以执行,其他的线程只能等待synchronized锁被释放。所以这三个关键子配合在一起用来控制线程是否持有synchronized锁。
notifyAll是通知所有阻塞的线程结束等待,notify则是通知一个线程结束等待,值得一提的是,它是公平的,也就是说,谁先调用wait,谁就将第一个收到通知。
另外wait方法还有两个重载方法:
//等待一定时长,超过时长,尝试去获取锁,执行代码
public final native void wait(long timeout)
public final void wait(long timeout, int nanos)
其中wait(long timeout, int nanos)的作用是为了更好的控制时间精度,看下它的源码就明白它的处理逻辑了:
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
如果nanos > 0,那么timeout就+1,timeout的单位是毫秒。看上去,这个参数的作用不明显,不过是在原来的参数上加1罢了,具体这么做的意义是什么呢?我暂时还没弄明白,等我弄明白了再补充。