线程状态转换

本文详细解析了Java中线程的生命周期,包括初始、可运行、运行、阻塞及终止等状态,并阐述了start()、sleep()、yield()、wait()等方法的作用及其对线程状态的影响。
小小的作下解释:

  1、线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了这个对象后,线程就进入了初始状态;

  2、当该对象调用了start()方法,就进入可运行状态;

  3、进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;

  4、进入运行状态后情况就比较复杂了

  4.1、run()方法或main()方法结束后,线程就进入终止状态;

  4.2、当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;

  4.3、线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到可运行状态,这时与其他进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态;

  4.4、当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;

  4.5、当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。

线程状态之间的转换关系是理解Java并发编程的重要基础。Java中线程的状态由`Thread.State`枚举类定义,主要包括以下六种状态:NEW(新建)、RUNNABLE(可运行/运行)、BLOCKED(阻塞)、WAITING(无时限等待)、TIMED_WAITING(有时限等待)和TERMINATED(终止)。这些状态之间通过特定的操作进行转换。 ### 线程状态及其转换 #### 1. **NEW -> RUNNABLE** 当一个线程被创建并调用`start()`方法时,它从`NEW`状态进入`RUNNABLE`状态。此时,线程处于就绪队列中,等待操作系统调度其执行[^2]。 #### 2. **RUNNABLE <-> RUNNING** `RUNNABLE`状态表示线程可以被执行,但尚未获得CPU时间片;一旦获得CPU资源,线程进入`RUNNING`状态,即实际在执行任务。这种转换是由操作系统内核调度器完成的,开发人员无法直接控制这一过程[^1]。 #### 3. **RUNNABLE -> BLOCKED** 线程尝试获取一个已经被其他线程持有的锁时会进入`BLOCKED`状态。例如,在尝试进入同步代码块或方法时,如果锁不可用,则当前线程会被挂起直到锁变得可用[^2]。 #### 4. **RUNNABLE -> WAITING** 线程调用`Object.wait()`、`Thread.join()`或者`LockSupport.park()`等方法后会进入`WAITING`状态,这意味着该线程将无限期地等待某个条件的发生。要从这个状态恢复,必须有其他线程显式唤醒它(如通过`notify()`或`notifyAll()`)[^3]。 #### 5. **RUNNABLE -> TIMED_WAITING** 与`WAITING`类似,但此状态下线程会在指定的时间后自动恢复。常见的触发方式包括调用带有超时参数的方法,比如`Thread.sleep(long millis)`、`Object.wait(long timeout)`、`Thread.join(long millis)`以及`LockSupport.parkNanos()`或`LockSupport.parkUntil()`[^3]。 #### 6. **BLOCKED/WAITING/TIMED_WAITING -> RUNNABLE** 当导致线程阻塞的原因解除后,线程会重新回到`RUNNABLE`状态,并再次参与CPU资源的竞争。这可能是因为锁释放、等待条件满足或是超时结束等原因。 #### 7. **RUNNABLE -> TERMINATED** 线程正常退出其`run()`方法或因异常而提前终止时,将进入`TERMINATED`状态。一旦到达此状态,线程的生命期结束,不能再被启动。 ### 状态转换图示例 虽然不能直接绘制图形,但可以通过文字描述来构建一个简单的状态转换图: ``` [NEW] | v [RUNNABLE] <--> [RUNNING] | \ / | \ / v v v [BLOCKED][WAITING][TIMED_WAITING] \ / \ / v [TERMINATED] ``` 在这个模型中,箭头指示了不同状态之间的可能转换路径。需要注意的是,某些转换需要特定的事件触发,如外部通知、超时到期等。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值