线程的sleep、yield、join、停止方法
wait()方法只能在同步方法中或同步块中调用。如果调用wait()时,没有持有适当的锁,会抛出异常;
方法notify()、notifyAll()也要在同步方法或同步块中调用;
1.wait()
使当前执行代码的线程进行等待;
wait()方法执行后,当前线程释放对象锁(即这个资源),当前线程被阻塞,其他线程能够拿到锁(资源)去执行代码;
2.notify()
唤醒等待的线程;
在notify()方法后,会释放对象锁,但当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退 出同步代码块之后才会释放对象锁;并且唤醒因为调用wait方法而被阻塞的线程;
public class Test {
public static void main(String[] args) {
Object object = new Object();
new Thread(() -> {
synchronized(object) {//锁object对象 主线程和子线程都竞争object这个资源
System.out.println(Thread.currentThread().getName()+"线程notify开始");
object.notify();
System.out.println(Thread.currentThread().getName()+"线程notify结束");
}
}).start();//子线程
//主线程
synchronized(object) {
System.out.println(Thread.currentThread().getName()+"线程wait开始");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程wait结束");
}
}
}
结果:
从结果图也可以看出:main线程(主线程)调用wait方法之后,主线程被阻塞,就释放了对象锁,使子线程Thread-0获取到对象锁,Thread-0(子线程)调用notify方法唤醒被阻塞的主线程后,把该子线程里面的代码块执行完毕后才释放的对象锁,使main线程再次获取到对象锁,继续执行;
3.notifyAll()
唤醒所有等待线程;
notify()是只能唤醒一个等待线程;
但是只有一个等待队列时,唤醒所有线程一定会造成不该唤醒的线程又被唤醒然后再次阻塞,造成性能开销;
其用法和notify()用法一致;