== Javaの学習> Javaスレッドのライフサイクルと状態スイッチ

A、Javaスレッドのライフサイクルと状態のスイッチ

これらの状態の説明は、次のようにまとめることができます。

新着

新しく作成されたが、まだそれはNEW状態にあるJavaスレッドのインスタンスを起動していません

パブリック クラスアプリの{

  パブリック 静的 ボイドメイン(文字列[]引数){

    スレッドスレッド = 新しいスレッド();

    Thread.State状態 = thread.getState()。

    System.out.println(状態)。
  }
}

// 出力 
NEW

RUNNABLE

JavaスレッドインスタンスがThread.start()メソッドを呼び出したときに、実行可能状態に入り、実行可能状態は、2つのサブステートで構成:READYとRUNNING。

  • READY:この状態のスレッドのスケジューリングは、より多くのスレッドスケジューラの状態を実行しているように変更することができます。
  • 実行:この状態は、スレッドが実行中であることを示し、コードに対応するスレッドオブジェクト指示run()メソッドは、CPUが実行されます。

JavaスレッドインスタンスThread.yield()メソッドは、スレッドスケジューラため、またはスケジューリングの、スレッドインスタンスと呼ばれたときの状態は、状態がまだRUNNABLEで取得するには、スレッドの状態()からREADYにRUNNINGから変更される可能性があるが、Thread.getState。例えば:

パブリック クラスアプリの{

  パブリック 静的 ボイドメイン(文字列[]引数){

    スレッドのスレッド = 新しいスレッド(() - > {

      Thread.yield();

      System.out.println("testThreadState");
    });

    thread.start();

    Thread.State state = thread.getState();

    System.out.println(state);
  }
}

// 输出结果
RUNNABLE
testThreadState

BLOCKED

阻塞状态,该状态下的线程不会被CPU分配执行时间,线程的状态为 BLOCKED的时候有两种可能的情况:

  • 线程正在等待一个监视器锁,只有获取监视器锁之后才能进入synchronized代码块或者synchronized方法,在此等待获取锁的过程线程都处于阻塞状态。
  • 线程X已步入synchronized代码块或者synchronized方法后(此时已经释放监视器锁)调用Object.wait()方法之后进行阻塞,当接收其他线程T调用该锁对象Object#notify()/notifyAll(),但是线程T尚未退出它所在的synchronized代码块或者synchronized方法,那么线程X依然处于阻塞状态(注意API注释中的reenter,理解它场景2就豁然开朗)。 
public class App {

  public static void main(String[] args) {
    App app = new App();

    Thread thread1 = new Thread(() -> {
      app.produce();
    });

    Thread thread2 = new Thread(() -> {
      app.consumer();
    });

    thread1.start();
    thread2.start();
    System.out.println("thread1:" + thread1.getState());
    System.out.println("thread2:" + thread2.getState());
  }

  public void produce() {
    synchronized (this) {
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  public void consumer() {
    synchronized (this) {
      System.out.println("testThread");
    }
  }
}

// 输出结果
thread1:RUNNABLE
thread2:BLOCKED
testThread
第一种情况

thread1先运行,拿到 synchronized 锁,执行 produce方法中的 synchronized 代码块中的代码-->等待5秒,这时候 thread2 再运行,状态为 BLOCKED,等到 thread1执行 synchronized代码块结束,thread2 拿到 synchronized 锁,才能执行 consume 方法中的 synchronized 代码块中的代码。

public class App {

  public static void main(String[] args) throws InterruptedException {
    App app = new App();

    Thread thread1 = new Thread(() -> {
      app.produce();
    });

    Thread thread2 = new Thread(() -> {
      app.consumer();
    });

    thread1.start();
    thread2.start();
    // 这里让主线程sleep 1500毫秒从而让thread2调用了notify()并且尚未退出synchronized代码块,确保thread1执行了wait()
    Thread.sleep(1500);
    System.out.println("thread1:" + thread1.getState());
    System.out.println("thread2:" + thread2.getState());
  }

  public void produce() {
    synchronized (this) {
      try {
        this.wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  public void consumer() {
    synchronized (this) {
      try {
        this.notify();
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("testThread");
    }
  }
}

// 输出结果
thread1:BLOCKED
thread2:TIMED_WAITING
testThread
第二种情况

thread1先运行,执行 wait() 方法进入 WAITING状态并释放锁,thread2再执行,执行 notify()方法唤醒 thread1,本来 thread1应该变化为 RUNNABLE状态,但是因为 thread2的synchronized代码块还没执行完,后面还有一个 Thread.sleep(3000)没执行完,thread2还拿着这把锁,所以,thread1就还是BLOCKED阻塞状态。

WAITING

无限期的等待状态,这种状态下的线程不会被CPU分配执行时间。当一个线程执行了某些方法后就会进入 WAITING 状态,被显式唤醒后又变化为 RUNNABLE状态继续执行。

RUNNABLE 转换为 WAITING 的方法:

  • Object#wait()
  • Thread#join()
  • LockSupport.park()

WAITING 转换为 RUNNABLE 的方法:

  • Object#notify()或者Object#notifyAll()
  • LockSupport.unpark(thread)
public class App {

  public static void main(String[] args) throws InterruptedException {
    App app = new App();

    Thread thread = new Thread(() -> {
      app.produce();
    });

    thread.start();
    // 这里让主线程sleep 1500毫秒,确保thread执行了wait()
    Thread.sleep(1500);
    System.out.println("thread:" + thread.getState());
  }

  public void produce() {
    synchronized (this) {
      try {
        this.wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

// 输出结果
thread:WAITING

TIMED_WAITING

有限期等待状态,它和WAITING有点相似,这种状态下的线程不会被分配CPU执行时间,不过这种状态下的线程不需要被显式唤醒,只需要等待超时限期到达就会被唤醒。 

RUNNABLE转换为TIMED_WAITING的方法:

  • Object#wait(timeout)
  • Thread#sleep(timeout)
  • Thread#join(timeout)
  • LockSupport.parkNanos(timeout)
  • LockSupport.parkUntil(timeout)

待超时时间结束,就由TIMED_WAITING状态转换为RUNNABLE状态。

public class App {

  public static void main(String[] args) throws InterruptedException {
    App app = new App();

    Thread thread = new Thread(() -> {
      app.produce();
    });

    thread.start();
    // 这里让主线程sleep 50毫秒,确保thread执行了Thread.sleep(3000)
    Thread.sleep(50);
    System.out.println("thread:" + thread.getState());
  }

  public void produce() {
    synchronized (this) {
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

// 输出结果
thread:TIMED_WAITING

TERMINATED

TERMINATED状态表示线程已经终结。一个线程实例只能被启动一次,准确来说,只会调用一次Thread#run()方法,Thread#run()方法执行结束之后,线程状态就会更变为TERMINATED,意味着线程的生命周期已经结束。

public class App {

  public static void main(String[] args) throws InterruptedException {
    App app = new App();

    Thread thread = new Thread(() -> {
      app.produce();
    });

    thread.start();
    // 这里让主线程sleep 50毫秒,确保thread执行了synchronized代码块中的代码
    Thread.sleep(50);
    System.out.println("thread:" + thread.getState());
  }

  public void produce() {
    synchronized (this) {
      System.out.println("testThread");
    }
  }
}
// 输出结果
testThread
thread:TERMINATED

おすすめ

転載: www.cnblogs.com/L-Test/p/12112480.html