java多线程学习 基础篇(五) java线程的状态


线程的状态

Thread.State这个枚举类,定义了线程的六种状态。

 1 public enum State {
 2     /**
 3      * Thread state for a thread which has not yet started.
 4      */
 5      /**
 6      * 处于NEW状态的线程此时尚未启动。
 7      * 指的是线程建好了,但是并没有调用Thread实例的start()方法。
 8      */
 9     NEW,
10 
11     /**
12      * Thread state for a runnable thread.  A thread in the runnable
13      * state is executing in the Java virtual machine but it may
14      * be waiting for other resources from the operating system
15      * such as processor.
16      */
17      /**
18      * Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
19      *    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。
20      *  该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。
21      *  就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
22      */
23     RUNNABLE,
24 
25     /**
26      * Thread state for a thread blocked waiting for a monitor lock.
27      * A thread in the blocked state is waiting for a monitor lock
28      * to enter a synchronized block/method or
29      * reenter a synchronized block/method after calling
30      * {@link Object#wait() Object.wait}.
31      */
32      /**
33      * 阻塞状态。处于BLOCKED状态的线程正等待锁的释放以进入同步区。
34      * 举个例子:比如你在小卖部窗口买东西(假设小卖部只有一个窗口),你前面有一个正在买东西,这个时候你必须要等待前面的人走了之后才可以买东西。
35      * 假设你是线程t2,你前面的那个人是线程t1。此时t1占有了锁(小卖部唯一的窗口),t2正在等待锁的释放,所以此时t2就处于BLOCKED状态。
36      */
37     BLOCKED,
38 
39     /**
40      * Thread state for a waiting thread.
41      * A thread is in the waiting state due to calling one of the
42      * following methods:
43      * 
    44 *
  • {@link Object#wait() Object.wait} with no timeout
  • 45 *
  • {@link #join() Thread.join} with no timeout
  • 46 *
  • {@link LockSupport#park() LockSupport.park}
  • 47 *
48 * 49 *

A thread in the waiting state is waiting for another thread to 50 * perform a particular action. 51 * 52 * For example, a thread that has called Object.wait() 53 * on an object is waiting for another thread to call 54 * Object.notify() or Object.notifyAll() on 55 * that object. A thread that has called Thread.join() 56 * is waiting for a specified thread to terminate. 57 */ 58 /** 59 * 等待状态。处于等待状态的线程变成RUNNABLE状态需要其他线程唤醒,等待其他线程做出一些特定动作(通知或中断)。 60 * 举个例子:这个时候经过你几分钟的等待,前面的人(t1)买好东西走了,这个时候你(t2)获得了锁(就是来到了窗口前), 61 * 但是有个人非常不友好的把你叫走了(假设他是t3),这个时候你就不得不释放掉刚刚得到的锁,此时你的状态就是WAITING状态。 62 * 要是t3不主动唤醒你t2(notify、notifyAll..),可以说你t2只能一直等待了。 63 */ 64 WAITING, 65 66 /** 67 * Thread state for a waiting thread with a specified waiting time. 68 * A thread is in the timed waiting state due to calling one of 69 * the following methods with a specified positive waiting time: 70 *

    71 *
  • {@link #sleep Thread.sleep}
  • 72 *
  • {@link Object#wait(long) Object.wait} with timeout
  • 73 *
  • {@link #join(long) Thread.join} with timeout
  • 74 *
  • {@link LockSupport#parkNanos LockSupport.parkNanos}
  • 75 *
  • {@link LockSupport#parkUntil LockSupport.parkUntil}
  • 76 *
77 */ 78 /** 79 * 超时等待状态。线程等待一个具体的时间,时间到后会被自动唤醒。 80 * 举个例子:t3唤醒你之后,你来到了小卖部窗口前。但是不巧的是又来了个人(t4)说让你等5分钟再买,去帮他拿一下快递。这时你还是线程t2,让你拿快递的人是线程t4。 81 * t4让t2等待了指定时间,t2先主动释放了锁。此时t2等待期间就属于TIMED_WATING状态。t2等待10分钟后,就自动唤醒,拥有了去争夺锁的资格。 82 */ 83 TIMED_WAITING, 84 85 /** 86 * Thread state for a terminated thread. 87 * The thread has completed execution. 88 */ 89 /** 90 * 终止状态。此时线程已执行完毕。 91 * 举个例子:你已经买到了你想要的东西,整个线程结束。 92 */ 93 TERMINATED; 94 }

 

线程的状态变化图

BLOCKED与RUNNABLE状态的转换

 代码如下:

 1 public enum State {
 2     /**
 3      * 处于NEW状态的线程此时尚未启动。
 4      * 指的是线程建好了,但是并没有调用Thread实例的start()方法。
 5      */
 6     NEW,
 7     /**
 8      * 表示当前线程正在运行中。处于RUNNABLE状态的线程在Java虚拟机中运行,也有可能在等待其他系统资源(比如I/O)
 9      */
10     RUNNABLE,
11     /**
12      * 阻塞状态。处于BLOCKED状态的线程正等待锁的释放以进入同步区。
13      * 举个例子:比如你在小卖部窗口买东西(假设小卖部只有一个窗口),你前面有一个正在买东西,这个时候你必须要等待前面的人走了之后才可以买东西。
14      * 假设你是线程t2,你前面的那个人是线程t1。此时t1占有了锁(小卖部唯一的窗口),t2正在等待锁的释放,所以此时t2就处于BLOCKED状态。
15      */
16     BLOCKED,
17     /**
18      * 等待状态。处于等待状态的线程变成RUNNABLE状态需要其他线程唤醒。
19      * 举个例子:这个时候经过你几分钟的等待,前面的人(t1)买好东西走了,这个时候你(t2)获得了锁(就是来到了窗口前),
20      * 但是有个人非常不友好的把你叫走了(假设他是t3),这个时候你就不得不释放掉刚刚得到的锁,此时你的状态就是WAITING状态。
21      * 要是t3不主动唤醒你t2(notify、notifyAll..),可以说你t2只能一直等待了。
22      */
23     WAITING,
24     /**
25      * 超时等待状态。线程等待一个具体的时间,时间到后会被自动唤醒。
26      * 举个例子:t3唤醒你之后,你来到了小卖部窗口前。但是不巧的是又来了个人(t4)说让你等5分钟再买,去帮他拿一下快递。这时你还是线程t2,让你拿快递的人是线程t4。
27      * t4让t2等待了指定时间,t2先主动释放了锁。此时t2等待期间就属于TIMED_WATING状态。t2等待10分钟后,就自动唤醒,拥有了去争夺锁的资格。
28      */
29     TIMED_WAITING,
30     /**
31      * 终止状态。此时线程已执行完毕。
32      * 举个例子:你已经买到了你想要的东西,整个线程结束。
33      */
34     TERMINATED;
35 }

结果如下:

>>>
a:TIMED_WAITING
b:BLOCKED

WAITING状态与RUNNABLE状态的转换

使线程从RUNNABLE状态转为WAITING状态可以使用Object.wait()Thread.join()方法
 1 public class ThreadState {
 2 
 3     public static void main(String[] args) throws InterruptedException {
 4         blockedTest();
 5     }
 6 
 7     public static void blockedTest() throws InterruptedException {
 8 
 9         Thread a = new Thread(new Runnable() {
10             @Override
11             public void run() {
12                 test();
13             }
14         }, "a");
15         Thread b = new Thread(new Runnable() {
16             @Override
17             public void run() {
18                 test();
19             }
20         }, "b");
21 
22         a.start();
23         a.join();// 这里调用join方法,join()方法不会释放锁,会一直等待当前线程执行完毕(转换为TERMINATED状态)。
24         b.start();
25         System.out.println(a.getName() + ":" + a.getState()); // 输出?
26         System.out.println(b.getName() + ":" + b.getState()); // 输出?
27     }
28 
29     public static synchronized void test() {
30         try {
31             Thread.sleep(2000L);
32         } catch (InterruptedException e) {
33             e.printStackTrace();
34         }
35     }
36 }

结果如下:

>>>
a:TERMINATED
b:TIMED_WAITING

TIMED_WAITING与RUNNABLE状态转换

TIMED_WAITING与WAITING状态类似,只是TIMED_WAITING状态等待的时间是指定的。
  • Thread.sleep(long):使当前线程睡眠指定时间。需要注意这里的“睡眠”只是暂时使线程停止执行,并不会释放锁。时间到后,线程会重新进入RUNNABLE状态。
  • Object.wait(long):wait(long)方法使线程进入TIMED_WAITING状态。这里的wait(long)方法与无参方法wait()相同的地方是,都可以通过其他线程调用notify()或notifyAll()方法来唤醒。不同的地方是,有参方法wait(long)就算其他线程不来唤醒它,经过指定时间long之后它会自动唤醒,拥有去争夺锁的资格。
  • Thread.join(long):join(long)使当前线程执行指定时间,并且使线程进入TIMED_WAITING状态。