引入问题:
需求: 有时候需要 锁住 或 暂停 运算线程, 需要等待外部事件 或者 等待固定时长 后唤醒和恢复工作。
实现方式有: (1)使用 Thread.sleep(2000) 方式让线程直接睡下去,并在固定时长后自动唤醒。
(2)使用对象锁实现,在其他线程唤醒此对象。
注: 两者是有很大区别的。第(1)种实现方式是线程直接睡,不出让系统资源。相反第(2)种线程就会出让系统资源。 此文只记录第(2)种方式实现。
实现(2)方式:
java每个对象都会有wait()\notify()等的方法。用这个可以实现锁住,并暂停在锁位置。 所在线程有此对象锁, 线程也会被锁,实质不是锁上,线程会出让系统资源。即线程因为此对象的等待而不工作。
可以等待固定时间; 可以用其他线程执行 notify()来唤醒此对象,即唤醒此线程。
(1)全局对象,用于标志等待和唤醒。
private Object mLockFlagObject = new Object();
(2)在工作线程中,想要暂停的位置执行此等待,等待别的线程来唤醒此对象。
synchronized (mLockFlagObject) {
mLockFlagObject.wait();
}
(3)在其他线程中执行notify()唤醒此对象,从而工作线程等待解除。
synchronized (mLockFlagObject) {
mLockFlagObject.notifyAll();
}
注:
(1)需要加上synchronized (mLockFlagObject) { } 这个来获取到mLockFlagObject的锁域,即监视器。否则会报错误如:java.lang.IllegalMonitorStateException
(2)多个线程可以同时在一个对象上等待。
(3)notify()是随机唤醒一个在对象上等待的线程, 若没有等待的线程,则不做任何操作。
(4)notifyAll()是唤醒等待池中的所有对象。
(5)notify()唤醒线程,并不是在notify()执行以后立即唤醒,而是在notify()线程释放了对象监视器后才真正执行被唤醒的线程。