介绍:
在程序中,我们是不能随便中断一个线程的,因为这是极其不安全的操作,我们无法知道这个线程正运行在什么状态,它可能持有某把锁,强行中断可能导致锁不能释放的问题;或者线程可能在操作数据库,强行中断导致数据不一致混乱的问题。正因此,JAVA里将Thread的stop方法设置为过时,以禁止大家使用。
一个线程什么时候可以退出呢?当然只有线程自己才能知道。
所以我们这里要说的Thread的interrupt()方法,本质不是用来中断一个线程。是将线程设置一个中断状态。
当我们调用线程的interrupt()方法(即调用threadxxx.interrupt()),它有两个作用:
1、如果此线程处于阻塞状态(比如调用了wait方法,io等待),则会立马退出阻塞,并抛出InterruptedException异常,线程就可以通过捕获InterruptedException来做一定的处理,然后让线程退出。
2、如果此线程正处于运行之中,则线程不受任何影响,继续运行,仅仅是线程的中断标记被设置为true。所以线程要在适当的位置通过调用isInterrupted()方法来查看自己是否被中断,并做退出操作。
--抄自
线程常用写法:
1、重写run方法时,常用的做法是在run方法内用 while (!Thread.interrupted()) 包裹代码块,以便当线程处于中断状态时,能退出while循环从而结束run方法(即结束线程)
PS: interrupted() 与 isInterrupted() 的区别:
interrupted()是静态方法:返回当前中断标志后,会重置当前线程的中断标识为false
isInterrupted()是实例方法,返回当前中断标志,不会重置线程的中断状态
2、当线程处于阻塞状态过程中,如果此时有其他地方将线程的中断标志试图改成ture,则会抛出InterruptedException,并且中断标志仍然是false,因此需要在catch块里调用Thread.currentThread().interrupt(); 以保证线程的中断标志是true,以便经过while时,能结束run方法。示例代码如下:
1 @Override
2 public void run() {
3 while (!Thread.interrupted()) {
4 try {
5 System.out.println("线程执行");
6 Thread.sleep(10 * 1000);
7 } catch (InterruptedException e) {
8 // 抛出中断异常后,会自动清除中断状态,因此需要调用interrupt()重新设置中断状态
9 Thread.currentThread().interrupt();
10 }
11 }
12 }
3、结束线程池需要按照jdk_api建议的方式,分两个阶段关闭 ExecutorService。第一阶段调用 shutdown 拒绝传入任务,然后调用 shutdownNow(如有必要)取消所有遗留的任务。代码示例如下:
1 void shutdownAndAwaitTermination(ExecutorService pool) {
2 pool.shutdown(); // Disable new tasks from being submitted
3 try {
4 // Wait a while for existing tasks to terminate
5 if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
6 pool.shutdownNow(); // Cancel currently executing tasks
7 // Wait a while for tasks to respond to being cancelled
8 if (!pool.awaitTermination(60, TimeUnit.SECONDS))
9 System.err.println("Pool did not terminate");
10 }
11 } catch (InterruptedException ie) {
12 // (Re-)Cancel if current thread also interrupted
13 pool.shutdownNow();
14 // Preserve interrupt status
15 Thread.currentThread().interrupt();
16 }
17 }