线程的几个状态

  • NEW 线程尚未开始执行状态. 还没有执行 start()
  • RUNNABLE 运行线程的状态,在JVM中处于运行状态中的Thread可能需要等待操作系统的资源,例如CPU
  • BLOCKED 线程阻塞等待获取锁🔒。进入一个 synchronized 同步块或者是同步方法,或者是重入一个 synchronized 同步块或者是同步方法
  • WAITING 线程处于waiting状态,是由于调用了一下几个方法,一个线程处于该状态是正在等待另一个线程执行特定的动作
    • Object.wait with no timeout
    • Thread.join with no timeout
    • LockSupport.park
    • 例子
      • 一个线程调用 object 上的 object.wait() 是等待另外一个线程执行特定的 object 上的 Object.notify() 或者是 Object.notifyAll()
      • 一个线程调用 Thread.join() 是等待另外一个线程来中断。
  • TIMED_WAITING 线程等待一个具体的时间,由于掉用了以下几个方法
    • Thread.sleep
    • Object.wait with timeout
    • Thread.join with timeout
    • LockSupport.parkNanos
    • LockSupport.parkUntil
  • TERMINATED 线程已经执行完成

    NEW

    1. final Thread thread = new Thread(() -> System.out.println("xxx"));
    2. System.out.println(thread.getState());

    RUNNABLE AND TERMINATED

    1. final Thread thread = new Thread(() -> {
    2. while (!Thread.currentThread().isInterrupted()) {
    3. int i = 0;
    4. }
    5. System.out.println("gg");
    6. });
    7. thread.start();
    8. Thread.sleep(100);
    9. System.out.println(thread.getState());
    10. thread.interrupt();
    11. Thread.sleep(5000);
    12. System.out.println(thread.getState());

    BLOCKED

    ```java public static void main(String[] args) throws Exception { {
    1. final Thread thread = new Thread(ThreadTest::method);
    2. thread.setName("thread1");
    3. thread.start();
    4. Thread.sleep(1000);
    5. System.out.println(thread.getState());//==>TIMED_WAITING
    } {
    1. final Thread thread = new Thread(ThreadTest::method);
    2. thread.setName("thread2");
    3. thread.start();
    4. Thread.sleep(1000);
    5. System.out.println(thread.getState());//==>BLOCKED
    } }

public static synchronized void method() { try { Thread.sleep(10000); } catch (InterruptedException ignore) { } }

  1. <a name="JLRKo"></a>
  2. #### WAITING
  3. ```java
  4. final Thread thread = new Thread(() -> {
  5. synchronized (lock) {
  6. try {
  7. lock.wait();
  8. } catch (InterruptedException e) { e.printStackTrace(); } }
  9. });
  10. thread.start();
  11. Thread.sleep(1000);
  12. System.out.println(thread.getState());//output ==> WAITING

TIMED_WAITING

  1. final Thread thread = new Thread(() -> {
  2. synchronized (lock) {
  3. try {
  4. lock.wait(5000);
  5. } catch (InterruptedException e) { e.printStackTrace(); } }
  6. });
  7. thread.start();
  8. Thread.sleep(1000);
  9. System.out.println(thread.getState());//output ==> TIMED_WAITING

熟练掌握线程掉几个运行状态在使用 jstack pid 的时候能够更加得心应手。对应 ThreadPool 中的Thread应该处于什么状态的理解会更加深刻。

线程状态转换

image.png

守护线程和非守护线程

以前看书的时候看到一个问题,JVM会在什么时候退出。在那个问题里边第一次见识到了 守护线程非守护线程 的概念。
其中一个答案就是,所有处于运行中的 非守护线程 都执行完毕了。

  • thread.setDaemon(false); 设置为非守护线程
  • thread.setDaemon(true); 设置为守护线程

如果不指定,默认用当前线程是否守护线程。

如果我想要main方法中JVM持续运行,不退出,只要Thread设置成非守护线程就可以了 ( 哈哈,main线程是非守护线程啦)

线程的几个方法

interrupt 中断

join

等待当前线程死亡,使用循环的wait来实现的。
使用场景: 主线程启动了一个子线程A,需要等待子线程A执行完毕后主线程在继续执行

  1. Thread a = new Thread(()->{});
  2. a.start();
  3. a.join();
  4. //继续执行

这个方式利用countdownlatch也是可以实现的。

yield

Java是线程执行是时间片分片执行的,使用yield让出自己的时间片,当然CPU可不听。

引申

1、start后能否再调用start (不能,会抛出IllegalThreadStateException)
2、java中的线程有哪几种状态(xdm自己去看源码),跟操作系统的有什么区别?
2.1、对应了linux系统中的pthread,操作系统的线程只有3中状态,分别是ready,runnable,waiting
3、如果用了setdemon什么效果?主线程和守护线程区别
3.1、守护线程,JVM不会退出
3.2、非守护线程,JVM会退出