wait和notify

6.1 wait/notify的机制

6.1.1 wait方法

方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程置入"预执行队列"中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止.在调用wait()方法之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法,执行完wait方法后,当前线程释放锁。(如果没有持有锁将会报错)

6.1.2 notify方法

在执行notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获得该对象锁,要等到执行notify方法的线程将程序执行完,也就是退出synchronized代码块之后,当前线程的锁才会被释放,而wait状态的线程才可以获得该对象的锁。
总之,wait使线程停止运行,而notify使停止的线程继续运行。

6.2 java线程状态图

image

说明: 线程共包括以下5种状态。
  1. 新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
  2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
  3. 运行状态(Running) : 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
  4. 阻塞状态(Blocked) : 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    (01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
    (02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
    (03) 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。
  5. 当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。死亡状态(Dead) : 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

6.3 相关API

API 解释
wait() 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)
wait(long timeout) 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)
wait(long timeout, int nanos) 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量”,当前线程被唤醒(进入“就绪状态”)
notify() 唤醒在此对象监视器上等待的单个线程
notifyAll() 唤醒在此对象监视器上等待的所有线程

你可能感兴趣的:(Java多线程编程,wait和notify)