注意在Java中,可以认为因为没有竞争到锁而无法执行下去的情况为【BLOCKED】,而调用wait方法之后的状态可以认为是【WAITING】.
image.png

假设有线程Thread t

情况1 NEW—>RUNNABLE

  • 当调用t.start()方法时,由【NEW】—>【RUNNABLE】,【NEW】状态的线程代表刚被创建的Java线程对象,但还没有关联操作系统。

    情况2 RUNNABLE<—>WAITING

    t线程用synchronized(obj)获取了对象锁后

  • 调用obj.wait()方法时,t线程从 【RUNNABLE】—>【WAITING】

  • 调用obj.notify(),obj.notifyAll(),t.interrupt()时

    1. -竞争锁成功,t线程从 WAITING】-->【RUNNABLE】<br /> -竞争锁失败,t线程从 WAITING】-->【BLOCKED

此种情况弄明白EntryList和WaitSet的机制即可,没有竞争到锁的线程会进入EntryList中,而只有调用wait方法的线程会进入WaitSet中,被唤醒后会进入EntryList中继续竞争锁。

情况3 RUNNABLE<—>WAITING

  • 当前线程调用t.join()方法时,当前线程从【RUNNABLE】—>【WAITING】,因为当前线程是要等待t线程运行结束后才能继续运行,所以陷入【WAITING】状态,注意是当前线程在t线程对象的监视器上等待
  • t线程运行结束,或调用了当前线程的interrupt()时,当前线程从【WAITING】—>【RUNNABLE】

    情况4 RUNNABLE<—>WAITING

  • 当前线程调用LockSupport.park()方法会让当前线程从【RUNNABLE】—>【WAITING】

  • 调用LockSupport.unpark(目标线程)或调用了线程的interrupt(),会让目标线程从【WAITING】—>【RUNNABLE】

    情况5 RUNNABLE<—>TIMED_WAITING

    t线程 用 synchronized(obj)获取了对象锁后

  • 调用obj.wait(long n)方法时,t线程从【RUNNABLE】—>【TIMED_WAITING】

  • t线程等待时间超过了n毫秒,,或调用obj.notify(),obj.notifyAll(),t.interrupt()时

    1. -竞争锁成功,t线程从【TIMED_WAITING】-->【RUNNABLE】<br /> -竞争锁失败,t线程从【TIMED_WAITING】-->【BLOCKED

    情况6 RUNNABLE<—>TIMED_WAITING

  • 当前线程调用t.join(long n)方法时,当前线程从【RUNNABLE】—>【TIMED_WAITING】,注意是当前线程在t线程对象的监视器上等待

  • 当前线程等待时间超过了n毫秒,或t线程运行结束,或调用了当前线程的interrupt()时,当前线程从【TIMED_WAITING】—>【RUNNABLE】

    情况7 RUNNABLE<—>TIMED_WAITING

  • 当前线程调用Thread.sleep(long n),当前线程从【RUNNABLE】—>【TIMED_WAITING】

  • 当前线程等待时间超过了n毫秒,当前线程从【TIMED_WAITING】—>【RUNNABLE】

    情况8 RUNNABLE<—>TIMED_WAITING

  • 当前线程调用LockSupport.parkNanos(long nanos)方法会让当前线程从【RUNNABLE】—>【TIMED_WAITING】

  • 调用LockSupport.unpark(目标线程)或调用了线程的interrupt(),或是等待超时,会让目标线程从【WAITING】—>【RUNNABLE】

    情况9 RUNNABLE<—>BLOCKED

  • t线程用synchronized(obj)获取了对象锁时如果竞争失败,从【RUNNABLE】—>【BLOCKED】

  • 持obj锁线程的同步代码块执行完毕,会唤醒该对象上所有【BLOCKED】的线程(EntryList上的所有线程)重新竞争,如果其中t线程竞争成功,从【BLOCKED】—>【RUNNABLE】,其它失败的线程仍然处于【BLOCKED】状态

    情况10 RUNNABLE<—>TERMINATED

    当前线程所有代码运行完毕,进入【TERMINATED】状态