Java并发机制(5)--线程、中断、Runnable、Callable、Future

本文详细介绍了Java线程的状态,包括阻塞与中断的机制,以及如何处理中断异常。讨论了取消与关闭线程的重要性,并对比了Runnable和Callable的区别,强调Callable在异常处理和结果获取上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Thread

线程的基本概念我们已经在深入理解Java并发机制(1)–理论基础中总结过了,这里不再赘述。

线程的状态

Java线程在其生命周期里处于以下6种状态,这些状态定义在Thread类内部枚举中。

状态 说明
NEW 初始态,还未调用start()方法
RUNNABLE 运行态,将操作系统中的就绪态和运行态统一定义为RUNNABLE
BLOCKED 阻塞态,线程等待获取锁
WAITING 等待态,线程等待其他线程做出一些特定状态(通知或中断)
TIME_WAITING 超时等待态,不同于等待态,超时后自行返回
TERMINATED 终止态,线程执行完毕

状态转移图如下:
这里写图片描述

从本质上讲,BLOCKED/WAITING/TIME_WAITING这三种状态都是等待状态,只不过分为三类便于管理。BLOCKED状态是获取锁而不得,WAITING状态是自己放弃执行等待某条件成熟。在需要竞争锁的场景下,这两者分别是阻塞队列和等待队列,阻塞队列竞争锁执行,等待队列等待条件成熟移至阻塞队列竞争锁继续执行。在不需要竞争锁的情况下,WAITING状态可以直接转为RUNNABLE。

阻塞与中断

当线程阻塞时,它通常处于BLOCKED/WAITING/TIME_WAITING状态,等待某个事件的发生(如:IO/锁的获取/sleep中醒来等)。线程阻塞和运行时间长的程序区别在于,阻塞的线程必须等待一个不受它自己控制的事件发生以后才能继续执行。

当一个方法抛出InterruptedException时,表示该方法是一个阻塞方法,如果这个方法被中断,那么它将尽力提前结束阻塞状态。

中断是线程的标志位属性,表示一个运行中的线程是否被其他线程进行了中断操作。中断是一种协作机制,当线程A中断线程B时,仅仅是要求B在执行到可以暂停的地方停止正在执行的工作—这经常用于取消某个操作,方法对中断的响应度越高,就越容易取消那些执行时间很长的操作。

当在代码中调用了一个将抛出InterruptedException的方法时,调用者也就变成了一个阻塞方法,重点是必须要对中断做相应的处理,一般有两种处理方式:

  • 传递InterruptedException:不做任何处理将中断情况传递给高层调用者,交由调用者处理
  • 恢复中断:当不能抛出InterruptException时,如Runnable中的run方法,捕获到了InterruptException后,调用线程的interrupt方法重新设置中断标志位,以便保持中断信息,供其他代码使用。

这两种方式对于中断的处理都是一个原则:不能无缘无故吃掉中断信息,保证中断信息可靠有效的传递给需要的代码。

取消与关闭

当我们启动一个线程后,如果我们对它失去控制将是一件很可怕的事情,想象一下当一个写文件的线程启动后,我们无法终止它,即使我们不想它继续写了,这很尴尬,在线程中加入控制手段是非常有必要的。

Java没有提供任何机制来安全的终止线程,但提供了线程协作机制—中断,通过中断,一个线程可以终止另外一个线程。

这里说终止,并不意味着线程A可以直接关闭线程B,而是指的是A可以通过interrupt(Thread t)方法去设置线程B的中断标志位。在线程B内有轮询代码(可中断的阻塞方法或者是外层循环代码)不断检查其中断标志位,如果发现已经被线程A中断,是抛出Interrupt-Exception,还是执行其他业务逻辑,还是执行相应的清理工作提前结束线程工作,取决于具体的逻辑需要。

Runnable与Callable

Java线程执行内容的定义有三种方式:

  • 继承Thread类,重写run()方法
  • 实现Runnable接口
  • 实现Callable接口

虽然有三种定义方式,但是本质上线程的启动都是通过Thread实例中的start方法来启动的(线程池的部分我们后面再讲)。

Runnable和Callable的区别和联系:

  • 区别:主要表现在两点:1、对异常的捕捉 2、线程执行结果的获取
  • 联系:Callable是对Runnable的补充,通过FutureTask类封装为Runnable类型

区别很明显,直接看代码:
Runnable:

public
interface Runnable {
   
   
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值