理解版
如果要形象地理解线程从创建到终止的整个生命周期。我们可以把线程执行理解成一个包裹的运送过程。
-
包裹揽收(New):
- 就像快递员接收到一个新的包裹,准备开始派送过程,线程在
new
关键字的作用下被创建。CourierThread courierThread = new CourierThread();
- 就像快递员接收到一个新的包裹,准备开始派送过程,线程在
-
分配路线(Runnable):
- 包裹被分配到一个派送路线上,线程通过调用
start()
方法,告知系统它已准备好开始执行。courierThread.start(); // 线程现在可以被调度执行
- 包裹被分配到一个派送路线上,线程通过调用
-
派送中(Running):
- 快递员正在路上派送包裹。线程获得CPU时间片,开始执行
run()
方法中的代码。class CourierThread extends Thread { public void run() { System.out.println("派送中..."); // 执行派送任务的代码 } }
- 快递员正在路上派送包裹。线程获得CPU时间片,开始执行
-
运输延迟(Blocked):
- 快递员遇到了交通堵塞或道路封闭,导致派送延迟。线程在等待获取资源(如锁)时进入阻塞状态。
synchronized (packageLocker) { // 访问包裹储物柜的代码 }
- 快递员遇到了交通堵塞或道路封闭,导致派送延迟。线程在等待获取资源(如锁)时进入阻塞状态。
-
等待进一步指示(Waiting):
- 快递员正在等待下一步的派送指示,线程在等待另一个线程的信号或动作。
Object instruction = ...; synchronized (instruction) { instruction.wait(); // 线程现在正在等待 }
- 快递员正在等待下一步的派送指示,线程在等待另一个线程的信号或动作。
-
等待放行(Timed Waiting):
- 快递员在检查站等待放行,这是线程等待有限时间的资源。
try { // 等待特定事件或条件的代码 Thread.sleep(waitingTime); } catch (InterruptedException e) { // 适当处理中断 }
- 快递员在检查站等待放行,这是线程等待有限时间的资源。
-
派送中断(Interrupted):
- 快递员接到紧急电话,需要更改派送路线或返回仓库。线程可以通过
interrupt()
方法被请求中断。// 处理中断的代码 courierThread.interrupt(); // 请求中断线程 try { // 执行派送任务的代码 } catch (InterruptedException e) { // 适当响应中断 }
- 快递员接到紧急电话,需要更改派送路线或返回仓库。线程可以通过
-
包裹送达(Terminated):
- 快递员成功将包裹送达目的地。线程完成它的
run()
方法,结束了它的生命周期。class CourierThread extends Thread { public void run() { // 执行派送任务的代码 System.out.println("包裹已送达。线程已终止。"); } }
- 快递员成功将包裹送达目的地。线程完成它的
专业版
在Java中,线程的生命周期包含几个明确的状态,并且在这些状态之间转换。当线程被意外中断时,它的行为会根据当前状态和线程如何处理中断而有所不同。下面我将详细解释每个状态,代码参看上面部分:
-
新建(New):线程对象被创建,但尚未启动。
-
可运行(Runnable):线程启动后,进入可运行状态,等待CPU时间片开始执行。
-
运行(Running):线程获得CPU时间片,开始执行
run()
方法中的代码。 -
阻塞(Blocked):线程等待获取一个监视器锁或其他资源时进入阻塞状态。
-
等待(Waiting):线程调用
wait()
、join()
或LockSupport.park()
等方法进入等待状态。 -
超时等待(Timed Waiting):线程调用带有超时参数的
wait()
、sleep()
或LockSupport.parkNanos()
等方法进入超时等待状态。 -
中断(Interrupted):线程可以通过调用
interrupt()
方法请求中断。如果线程在阻塞或等待状态,它会收到中断信号,并可能抛出InterruptedException
。 -
终止(Terminated):线程的
run()
方法执行完毕,线程进入终止状态。
在处理中断时,线程应该在run()
方法中适当地捕获InterruptedException
,并根据需要进行清理和资源释放。这样,即使线程被意外中断,也能优雅地处理中断,确保程序的稳定性和正确性。记住,中断一个线程并不会立即停止它的执行,而是设置了一个标志,线程需要检查这个标志并决定如何响应中断。