Java中我们可以通过一些手段关闭一个线程。关闭一个线程有两种方式:一种是强制关闭,比如说是exit退出当前线程,stop()方法强制关闭一个线程,Interrupt方法给一个线程打上标识,如果遇到阻塞的情况下抛出InterruptedException 结束线程。
其中使用stop方法的方式强制关闭线程的方式已经不推荐了,因为可能导致一些难以预料的后果,并且这些方法在新版本的Java API中已经标注为将要过期。现在一般使用Interrupt方法的方式来关闭线程。
Java Interrupt() 方法没法强制关闭一个线程,能够做的是给线程设置中断标志。
对于处于阻塞状态的线程调用interrupt()方法的时候,
会抛出一个InterruptException,并且结束线程的等待状态,直接跳转到异常处理的代码块。
也就是说,Interrupt方法可以结束处于阻塞状态的线程(比如调用sleep,join,wait方法而阻塞的线程)
我的代码和我的日志
代码:
import
java.util.Date;
public
class
InterrupteTest {
private
static
Object lock =
new
Object();
public
static
void
main(String[] args) {
// 测试线程调用sleep方法时被执行Interrupt
// 线程会被成功结束掉
Thread t1 =
new
Thread(() -> {
try
{
Thread.sleep(
10000
);
}
catch
(Exception e) {
System.out.println(
"Thread1 is interrupted "
+
new
Date().toString());
}
});
// 测试当一个线程处于wait状态时,被外部线程调用Interrupt方法
// 线程如果处于wait状态会被成功地结束掉
Thread t2 =
new
Thread(() -> {
try
{
syncMethod();
}
catch
(Exception e) {
System.out.println(
"Thread2 is interrupted "
+
new
Date().toString());
}
});
// 测试一个线程调用自己本身的interrupt()方法 -- 在线程阻塞之前调用
// 可以成功的把当前线程给结束掉
Thread t3 =
new
Thread(() -> {
try
{
Thread.currentThread().interrupt();
syncMethod();
}
catch
(InterruptedException e) {
System.out.println(
"Thread3 is interrupted"
+
new
Date().toString());
}
});
// 测试一个线程调用自己本身的interrupt()方法 -- 在线程阻塞之后调用
// Interrupt方法执行时,当前线程已经退出了阻塞状态,所以对当前线程没有影响
Thread t4 =
new
Thread(() -> {
try
{
syncMethod();
Thread.currentThread().interrupt();
}
catch
(InterruptedException e) {
System.out.println(
"Thread4 is interrupted"
+
new
Date().toString());
}
});
System.out.println(
"begin interrupt Thread1 "
+
new
Date().toString());
t1.setName(
"Thread1"
);
t1.start();
t1.interrupt();
System.out.println(
"begin interrupt Thread2 "
+
new
Date().toString());
t2.setName(
"Thread2"
);
t2.start();
t2.interrupt();
System.out.println(
"begin interrupt Thread3 "
+
new
Date().toString());
t3.setName(
"Thread3"
);
t3.start();
System.out.println(
"begin interrupt Thread4 "
+
new
Date().toString());
t4.setName(
"Thread4"
);
t4.start();
}
private
static
void
syncMethod()
throws
InterruptedException {
synchronized
(lock) {
System.out.println(Thread.currentThread().getName() +
" is calling syncMethod "
+
new
Date().toString());
lock.wait(
10000
);
}
}
}
日志:
begin interrupt Thread1 Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread2 Tue Jun 19 18:01:54 CST 2018
Thread1 is interrupted Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread3 Tue Jun 19 18:01:54 CST 2018
Thread2 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread4 Tue Jun 19 18:01:54 CST 2018
Thread2 is interrupted Tue Jun 19 18:01:54 CST 2018
Thread4 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
Thread3 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
Thread3 is interruptedTue Jun 19 18:01:54 CST 2018
对上面的代码的总结:
从上面的代码中可以看到的是
1:sleep和wait方法等待的线程都可以被Interrupt掉
2:如果一个线程自己调用自己的Interrupt方法的话,最好是在阻塞之前(在本示例代码中就是要在调用wait方法之前),因为当线程阻塞掉之后就没法继续执行逻辑。必须在线程等待之前就把线程状态标识为interrupted状态。