Java-notify和wait的理解
2021-03-04 本文已影响0人
hello_world_cxm
package day0304;
public class TestWaitNotify {
public static void main(String[] args) throws Exception{
Object o = new Object();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
synchronized (o) { //此时o的锁标记是空闲的,所以颁发给了t线程,t线程得以进入同步代码块 打印AB
System.out.println("A");
System.out.println("B");
o.notify(); //o呼叫在阻塞队列中的线程(即主线程)主线程离开o等待队列 但是没有拿到o的锁,调notify不会释放锁标识 然后继续往下执行
//打印完CD之后,t的锁标志就是被释放
System.out.println("C");
System.out.println("D");
}
}
});
t.start();
synchronized (o) {
System.out.println("1");
System.out.println("2");
//o是临界资源,多个线程来争夺使用权
o.wait(); //主线程释放o的锁标记 并且主线程放弃了cpu,主线程进入了o的阻塞队列。随后时间片给了子线程t,
System.out.println("3");
System.out.println("4");
}
}
}
上面可以用去银行柜员机取钱的例子来说明,前提是柜员机有个大笼子罩着,笼子上面有把锁,取钱的人,只有拿到这把锁,才可以关闭笼子,进行独自取钱。且柜员机是每时每刻都要有人取钱。
首先主线程取到笼子的锁,并锁住了笼子,别的线程就无法进来切断主线程的原子操作,但是主线程取完1 2之后,忽然想出去离开柜员机打个电话,此时则意味着主线程放弃了取钱这个原子操作,并且放弃了cpu,此时主线程打完电话之后,发现笼子里面有线程t了,自己进不去,没办法,只能在笼子外的等待队列中等待,等待里面的人取完钱。
此时t线程已经取完1 2,并且大喊一声:你从等待队列中出列,来到笼子门口,我准备取完了。此时,t线程继续取钱,直到取完D,然后就释放了锁,释放了cpu,进入了终止状态。
此时主线程早已在笼子门口等待多时,然后获得笼子的那把锁,然后进去柜员机,继续取 3 4,因为刚才1 2已经取完。
最后取完3 4之后,主线程也进行终止状态,此时两个线程都已经结束,完。