- 方法wait()使当前线程等待,释放锁,并且在wait方法处停止执行,直到接到通知或被中断为止;
- 调用wai()方法前必须获得该对象的对象级别锁,如果调用wait()时没有适当的锁,抛出IllegalMonitorStateException。
- notify()调用时也必须获得该对象的对象级别锁,若没有,抛出IllegalMonitorStateException;
- notify()方法用来通知那些可能等待该对象的对象锁的其他线程,若有多个,由线程规划器挑选一个,并使它获得该对象的对象锁;
- 执行notify()后,当前线程并不马上释放锁,wait状态线程也并不能马上获得锁,要等到notiry()方法的线程执行完退出synchronized块后才行。
一个例子
/**
* 等待通知机制的实现
* @author user1
*
*/
public class MyList313 {
private List<String> list = new ArrayList<>();
public void add(){
list.add("景");
}
public int getSize(){
return list.size();
}
public void m1(){
synchronized(list){
try {
if(list.size() != 5){
System.out.println("进入m1 wait"+System.currentTimeMillis());
list.wait();
System.out.println("离开m1 wait"+System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void m2(){
synchronized(list){
for(int i = 0;i<10;i++){
add();
if(list.size() == 5){
System.out.println("进入m2 notify"+System.currentTimeMillis());
list.notify();
System.out.println("离开m2 notify"+System.currentTimeMillis());
}
System.out.println("m2 中list的长度"+getSize());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
MyList313 m = new MyList313();
new Thread(new Runnable() {
@Override
public void run() {
m.m1();
}
}).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
m.m2();
}
}).start();
}
}
结果
notifyAll()方法可以使所有正在等待队列等待同一资源的全部线程从等待状态退出,进入可运行状态。此时,优先级最高的最先运行,但也有可能随机运行。