java中wait,notify,notifyAll,sleep方法的作用和区别
Posted Leo Han
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中wait,notify,notifyAll,sleep方法的作用和区别相关的知识,希望对你有一定的参考价值。
在进行多线程编程时,进程会遇到多线程之前的同步已经等待场景。
在java中,Object类提供了wait、nofity、notifyAll用来进行线程间的同步。一般如果我们调用wait、nofity、notifyAll都是结合synchronized同步关键字来使用:
new Thread(()->
synchronized (monitor)
try
System.out.println("1. enter monitor ");
Thread.sleep(5000);
System.out.println("1. call wait ");
monitor.wait();
System.out.println("1. get monitor again ");
Thread.sleep(5000);
System.out.println("1. call notify ");
monitor.notify();
System.out.println("1. finished");
catch (InterruptedException e)
e.printStackTrace();
).start();
new Thread(()->
synchronized (monitor)
try
System.out.println("2. enter monitor ");
Thread.sleep(5000);
System.out.println("2. call notify ");
monitor.notify();
System.out.println("2. get monitor again ");
Thread.sleep(5000);
System.out.println("2. call monitor ");
monitor.wait();
System.out.println("2. finished ");
catch (InterruptedException e)
e.printStackTrace();
).start();
打印:
1. enter monitor
1. call wait
2. enter monitor
2. call notify
2. get monitor again
2. call monitor
1. get monitor again
1. call notify
1. finished
2. finished
在java中每个对象都有一个对象锁,里面会维护一个EntryList 中保存目前等待获取锁的线程,WaitSet 保存 wait 的线程。我们调用wait方法时,已经获得了对象锁的线程会让出锁进行阻塞等待,将当前线程放入到waitSet ,而调用notify之后,当前线程也会让出锁,然后从对象锁的waitSet中去一个线程进行唤醒。
这里有几个点需要注意,
调用wait方法的调用方必须是synchronized锁的持有者
,如果是synchronized代码块,那么这个持有者就是同步的对象实例,如果是在类方法,那么就是这个类实例,如果在静态方法那么就是这个类本身- 调用wait方法前,必须获取synchronized锁,也就是调用wait方法必须在synchronized的作用范围内,如果在其他地方调用,则会报如下错误:
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at com.gridsum.ad.agg.query.platform.util.Utils.main(Utils.java:44)
- 调用wait方法后,线程进入阻塞等待,必须等待其他线程调用notify/notifyAll来进行唤醒
wait方法会释放当前已经获得的synchronized锁,直到其他线程调用notify/notifyAll唤醒重新竞争获取锁。
而Thread.sleep只是让线程进行休眠,不会释放任何锁资源。
而像Thread.sleep(0) 有点类似 Thread.yield(),表示出让当前CPU时间片,重新获取。
以上是关于java中wait,notify,notifyAll,sleep方法的作用和区别的主要内容,如果未能解决你的问题,请参考以下文章