1.wait和notify
wait會釋放鎖,notify不會釋放鎖。wait和notify隻能在加鎖的情況下使用。
wait底層是引用的native方法,wait一定的時間。
notify喚醒一個對象,底層是一個native方法,隻能被該對象的monitor調用。
某個線程調用對象的wait方法,該線程進入等待模式且釋放鎖。其他線程可以通路。wait可以取消while循環的等待模式,減少CPU的消耗。
其他線程當調用對象的notify方法時,notify會啟動正在等待該對象的一個線程,但是由于notify不會釋放鎖,是以被喚醒的線程也隻能在本線程結束後才能執行。
而且,notify喚醒的線程是由CPU線程排程器自動配置設定的。
是以如果想讓notify喚醒的鎖不用等待本線程的結束,需要本線程調用wait自動釋放鎖,然後notify喚醒的線程執行結束之前,需要喚醒剛才wait的線程。
能使用countdownlatch就不要用wait,notify
比wait和notify更好的方式,是用CountDownLatch(門闩)
舉個例子
//對于一個簡單的不涉及同步的程序,能用CountDownLatch就不要用sybchronized+wait+notify的方法。
volatile List list=new ArrayList();
CountDownLatch latch=new CountDownLatch(1);//初始值,減到0之後,門闩打開,線程得以運作
new Thread(()->{
if(list.size()!=5){
try{
latch.await();
//用門闩等待的時候不需要鎖定任何對象,await之後,線程在此停住。
}catch(InterruptedException e){
e.printStackTrace;
}
}
}).start();
new Thread(()->{
for(int i=0;i<10;i++){
list.add(new Object());
System.out.println("add"+i);
if(list.size()==5){
try{
latch.countDown();//每一次countDown(),初始值-1
//打開門闩,剛才的線程得以繼續運作
}catch(InterruptedException e){
e.printStackTrace;
}
}
}
}).start();