使用interrupt()中断线程
当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。
下面一段代码演示了休眠线程的中断:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public
class
SleepInterrupt
extends
Object
implements
Runnable{
public
void
run(){
try
{
System.out.println(
"in run() - about to sleep for 20 seconds"
);
Thread.sleep(
20000
);
System.out.println(
"in run() - woke up"
);
}
catch
(InterruptedException e){
System.out.println(
"in run() - interrupted while sleeping"
);
//处理完中断异常后,返回到run()方法人口,
//如果没有return,线程不会实际被中断,它会继续打印下面的信息
return
;
}
System.out.println(
"in run() - leaving normally"
);
}
public
static
void
main(String[] args) {
SleepInterrupt si =
new
SleepInterrupt();
Thread t =
new
Thread(si);
t.start();
//主线程休眠2秒,从而确保刚才启动的线程有机会执行一段时间
try
{
Thread.sleep(
2000
);
}
catch
(InterruptedException e){
e.printStackTrace();
}
System.out.println(
"in main() - interrupting other thread"
);
//中断线程t
t.interrupt();
System.out.println(
"in main() - leaving"
);
}
}
|
运行结果如下:
待决中断
在上面的例子中,sleep()方法的实现检查到休眠线程被中断,它会相当友好地终止线程,并抛出InterruptedException异常。另外一种情况,如果线程在调用sleep()方法前被中断,那么该中断称为待决中断,它会在刚调用sleep()方法时,立即抛出InterruptedException异常。
下面的代码演示了待决中断:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
PendingInterrupt
extends
Object {
public
static
void
main(String[] args){
//如果输入了参数,则在mian线程中中断当前线程(亦即main线程)
if
( args.length >
0
){
Thread.currentThread().interrupt();
}
//获取当前时间
long
startTime = System.currentTimeMillis();
try
{
Thread.sleep(
2000
);
System.out.println(
"was NOT interrupted"
);
}
catch
(InterruptedException x){
System.out.println(
"was interrupted"
);
}
//计算中间代码执行的时间
System.out.println(
"elapsedTime="
+ ( System.currentTimeMillis() - startTime));
}
}
|
如果PendingInterrupt不带任何命令行参数,那么线程不会被中断,最终输出的时间差距应该在2000附近(具体时间由系统决定,不精确),如果PendingInterrupt带有命令行参数,则调用中断当前线程的代码,但main线程仍然运行,最终输出的时间差距应该远小于2000,因为线程尚未休眠,便被中断,因此,一旦调用sleep()方法,会立即打印出catch块中的信息。执行结果如下:
使用isInterrupted()方法判断中断状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
InterruptCheck
extends
Object{
public
static
void
main(String[] args){
Thread t = Thread.currentThread();
System.out.println(
"Point A: t.isInterrupted()="
+ t.isInterrupted());
//待决中断,中断自身
t.interrupt();
System.out.println(
"Point B: t.isInterrupted()="
+ t.isInterrupted());
System.out.println(
"Point C: t.isInterrupted()="
+ t.isInterrupted());
try
{
Thread.sleep(
2000
);
System.out.println(
"was NOT interrupted"
);
}
catch
( InterruptedException x){
System.out.println(
"was interrupted"
);
}
//抛出异常后,会清除中断标志,这里会返回false
System.out.println(
"Point D: t.isInterrupted()="
+ t.isInterrupted());
}
}
|
运行结果如下:
使用Thread.interrupted()方法判断中断状态
可以使用Thread.interrupted()方法来检查当前线程的中断状态(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么,这个方法返回true。与isInterrupted()不同,它将自动重置中断状态为false,第二次调用Thread.interrupted()方法,总是返回false,除非中断了线程。
如下代码演示了Thread.interrupted()方法的使用:
1
2
3
4
5
6
7
8
9
10
11
|
public
class
InterruptReset
extends
Object {
public
static
void
main(String[] args) {
System.out.println(
"Point X: Thread.interrupted()="
+ Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println(
"Point Y: Thread.interrupted()="
+ Thread.interrupted());
System.out.println(
"Point Z: Thread.interrupted()="
+ Thread.interrupted());
}
}
|
运行结果如下:
从结果中可以看出,当前线程中断自身后,在Y点,中断状态为true,并由Thread.interrupted()自动重置为false,那么下次调用该方法得到的结果便是false。