线程状态转换

线程状态转换

img

  1. RUNNABLE <--> WAITING

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

      1. 调用obj.wait()方法时,t 线程从RUNNABLE --> WAITING
      2. 调用obj.notify(),obj.notifyAll(),t.interrupt()时
        1. 竞争锁成功,t 线程从WAITING --> RUNNABLE
        2. 竞争锁失败,t 线程从WAITING --> BLOCKED
    2. code:

      @Slf4j
      public class Test4 {
          final static Object obj = new Object();
      
          public static void main(String[] args) {
              new Thread(() -> {
                  synchronized (obj) {
                      log.debug("执行...");
                      try {
                          obj.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      log.debug("其他代码...");//断点
                  }
              }, "t1").start();
              new Thread(() -> {
                  synchronized (obj) {
                      log.debug("执行...");
                      try {
                          obj.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      log.debug("其他代码...");//断点
                  }
              }, "t2").start();
      
              try {
                  Thread.sleep(500);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              log.debug("唤醒obj上的其他线程");
              synchronized (obj) {
                  /**
                   * 这 obj.notifyAll();这行代码处设置断点,记得右键断点,将断点的模式设置为“线程”
                   * 然后一步步向下一行执行,可以看到断点在 obj.notifyAll();这一行时,
                   * t1,t2线程都是wait状态(idea中的wait即为waiting;monitor即为blocked状态);
                   * 断点在 obj.notifyAll();下一行时,t1,t2都为blocked状态,因为主线程还没有释放obj锁。
                   * 断点在 obj.notifyAll();下下一行时,t1,t2一个为blocked状态,一个为running状态,因为是只能有一个竞争到锁
                   */
                  obj.notifyAll(); // 唤醒obj上所有等待线程 断点
              }
          }
      }
      
      
  2. RUNNABLE <--> WAITING

    1. 当前线程调用 LockSupport.park() 方法会让当前线程从 RUNNABLE --> WAITING
    2. 调用 LockSupport.unpark(目标线程) 或调用了线程 的 interrupt() ,会让目标线程从 WAITING -->
      RUNNABLE
  3. RUNNABLE <--> WAITING

    1. 当前线程调用 t.join() 方法时,当前线程从 RUNNABLE --> WAITING
      注意是当前线程在t 线程对象的监视器上等待
    2. t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从 WAITING --> RUNNABLE
  4. RUNNABLE <--> TIMED_WAITING

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

    1. 调用 obj.wait(long n) 方法时,t 线程从 RUNNABLE --> TIMED_WAITING
    2. t 线程等待时间超过了 n 毫秒,或调用 obj.notify() , obj.notifyAll() , t.interrupt() 时
      1. 竞争锁成功,t 线程从 TIMED_WAITING --> RUNNABLE
      2. 竞争锁失败,t 线程从 TIMED_WAITING --> BLOCKED
  5. RUNNABLE <--> TIMED_WAITING

    1. 当前线程调用 t.join(long n) 方法时,当前线程从 RUNNABLE --> TIMED_WAITING
      注意是当前线程在t 线程对象的监视器上等待
    2. 当前线程等待时间超过了 n 毫秒,或t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从
      TIMED_WAITING --> RUNNABLE
  6. RUNNABLE <--> TIMED_WAITING

    1. 当前线程调用 Thread.sleep(long n) ,当前线程从 RUNNABLE --> TIMED_WAITING
    2. 当前线程等待时间超过了 n 毫秒或调用了线程 的 interrupt() ,当前线程从 TIMED_WAITING --> RUNNABLE
  7. RUNNABLE <--> TIMED_WAITING

    1. 当前线程调用 LockSupport.parkNanos(long nanos) 或 LockSupport.parkUntil(long millis) 时,当前线
      程从 RUNNABLE --> TIMED_WAITING
    2. 调用 LockSupport.unpark(目标线程) 或调用了线程 的 interrupt() ,或是等待超时,会让目标线程从
      TIMED_WAITING--> RUNNABLE
原文地址:https://www.cnblogs.com/jinronga/p/14427373.html