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 * <ul> 44 * <li>{@link Object#wait() Object.wait} with no timeout</li> 45 * <li>{@link #join() Thread.join} with no timeout</li> 46 * <li>{@link LockSupport#park() LockSupport.park}</li> 47 * </ul> 48 * 49 * <p>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 <tt>Object.wait()</tt> 53 * on an object is waiting for another thread to call 54 * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on 55 * that object. A thread that has called <tt>Thread.join()</tt> 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 * <ul> 71 * <li>{@link #sleep Thread.sleep}</li> 72 * <li>{@link Object#wait(long) Object.wait} with timeout</li> 73 * <li>{@link #join(long) Thread.join} with timeout</li> 74 * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> 75 * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> 76 * </ul> 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状态。