Sleep
- sleep语义:放弃CPU资源,并告诉操作系统未来N时间内不参与CPU资源竞争。由于是竞争,所以超过N时间,也可能仍竞争不到。
- sleep不释放资源锁:如果持有锁,则sleep时仍然持有。
- sleep可以被中断唤醒。
- sleep(0)语义:告诉系统重新进行一次CPU资源竞争,自己仍可能抢占到CPU资源。缺点是频繁执行会耗费大量CPU时间,优点是适当使用可以提高系统总体响应性能。
Wait和Notify和NotifyAll
- wait语义: wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行, 只有其他线程调用了notify方法调用wait方法的一个或多个线程就会解除wait状态,重新参与竞争对象锁,程序如果可以再次得到锁,就可以继续向下运行
- 必须在Object上执行:每个Object都有个内存锁,wait即对此进行unlock。
- 必须先Object.lock():wait即unlock之前,必须现在其他地方进行了lock,一般是synchronized处
- notify语义:并不unlock释放锁,告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还 在别人手里,别人还没释放。如果notify/notifyAll方法后面的代码还有很多,需要这些代码执行完后才会释放锁。一般是synchronized结束的时候自动unlock。
- 顺序依赖问题:如果先notify,再wait,则wait无法捕获notify的信号。park和unpark解决了顺序依赖问题。
- notify VS notifyall:都不释放锁,仅通知。notify随机通知一个,notifyall通知所有,然后所有开始排队竞争。notify可能导致死锁,因为可能唤醒一个不相干的wait线程,其处理完可能不执行notify,那么其他需要的线程会一直在wait中死等。
- wait和notify用来同步的object,一定要是同一个:例如,线程的this作为object的话,不能用于多个线程间,因为每个线程的this都是独立的,在自己的this上notify无法通知到另外线程的this上wait的。