本节主要来讲一讲线程的状态以及它的中断,就好像描述一个美女的外貌,是性感的,有气质的,还是可爱的(不是很恰当的比喻)。
- 线程的各种状态以及转换
New
Runnable
Waiting
TimedWaiting
Ready
Blocking
Terminated
- 线程的中断以及处理
interrupt、 interrupted、isinterrupted();
InterruptExeception
线程的各种状态以及转换
我们知道自然界每一个事物都有一种状态,水有三态,并且相互可以转换,那么线程也一样,它也有许多状态。
New:也就是初始态,表示一个线程刚刚开始准备好,这个状态下的线程只要调用start()就能开始运行。
Runnable:运行态,最好理解的一个状态,表示线程正在运行中。
Waiting:等待态,当线程调用wait()、join()或park()时会进入等待态,此时线程停下了匆匆的脚步,开始欣赏沿途的风景,此时会根据不同的通知选择继续执行任务或者放弃任务。
TimedWaiting:超时等待态,和等待态不同的是,超时等待态在等待某一段时间后会自动进入阻塞态,不需要别人的提醒,非常自觉。
Ready:就绪态,这个状态下的线程已经获得了所需要的资源,只需要一个指令,就能开始继续运行,就好像start指令,但是和初始态是完不同的,就绪态的线程是执行过任务的。
Blocking:阻塞态,当线程请求某一个资源失败的时候,就像一个线程请求某个资源的锁失败,进入了阻塞态。阻塞态中的线程如果再次请求这个资源成功,就会进入就绪态。
Terminated:终结态,当线程永远不再执行的状态。
上述线程的七个状态可以相互转换。
上图的状态转换图是对线程的状态一个非常好的总结。
线程的中断以及处理
线程的中断是用来执行线程停止的相关操作的,每一个线程都有一个boolean的变量来描述一个线程是否需要停止。当变量为true时,说明此线程需要停止工作,线程接下来就执行相关的退出操作,比如释放资源。所以,相比较stop,使用中断更加安全。
JDK中关于中断有三个常用的方法。
1
2
3
4 1void interrupt();//中断线程
2boolean isinterrupted();//判断是否被中断
3static boolean interrupted();//判断是否中断,并且清除中断状态。
4
使用中断需要注意的是:调用interrupted方法,还会清除当前线程的中断状态。
使用中断,我们可以优雅且安全的中断线程。具体如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 1@Override
2public void run() {
3 //线程没有中断时
4 while (!Thread.interrupted()) {
5 //做一些事
6 if(//做了坏事了){
7 //需要中断线程了
8 Thread.interrupt();//中断状态被设置为true
9 }
10 }
11 //线程被中断了
12 //做一些释放资源的事情
13 //........
14}
15
我们在while循环中不停地对线程的中断状态进行监听,如果发生中断了,则执行相应的安全收尾动作。
中断的处理
当线程执行sleep或者wait等方法时被中断,会抛出InterruptedException,表示线程sleep或者wait的太久了。当我们捕获到这个异常时,可以选择抛出也可以自己处理。但是当你往上抛出异常时一定要注意:捕获InterruptedException,会清除此线程的中断状态,也就是说我们还需要执行Thread.interrupt(),再次把线程的中断状态设置为true。
不可中断的线程
在java中,在某些情况下线程是不可中断的。在线程试图请求锁时,是不可以中断的;在线程执行I/O任务时,不可以中断线程。