并发编程学习笔记(三、如何安全地终止线程)

目录:

  • 设置退出标识
  • interrupt()方法
  • 总结

设置退出标识:

 1 public class FlagThread extends Thread {
 2     /**
 3      * 退出标识
 4      */
 5     public volatile boolean exit = false;
 6 
 7     @Override
 8     public void run() {
 9         while (!exit) {
10         }
11         System.out.println("ThreadFlag线程退出");
12     }
13 
14     public static void main(String[] args) throws Exception {
15         FlagThread threadFlag = new FlagThread();
16         threadFlag.start();
17         // 主线程延迟3秒
18         sleep(3000);
19         // todo 终止线程thread
20         threadFlag.exit = true;
21         // main线程放弃cpu使用权
22         // 让threadFlag线程继续执行,直到threadFlag运行完
23         threadFlag.join();
24         System.out.println("线程退出!");
25     }
26 }

通过第5行的exit属性来表示线程是否应该退出;但这种方法有一个弊端,若线程阻塞时标识便不起作用了。

interrupt()方法:

 1 public class InterruptThread extends Thread {
 2     /**
 3      * 退出标识
 4      */
 5     volatile boolean exit = false;
 6 
 7     @Override
 8     public void run() {
 9         while (!exit) {
10             System.out.println(getName() + " is running");
11             try {
12                 Thread.currentThread().join();
13             } catch (InterruptedException e) {
14                 System.out.println("week up from block...");
15                 // 在异常处理代码中修改共享变量的状态
16                 exit = true;
17             }
18         }
19         System.out.println(getName() + " is exiting...");
20     }
21 
22     public static void main(String[] args) throws InterruptedException {
23         InterruptThread interruptThread = new InterruptThread();
24         System.out.println("Starting thread...");
25         interruptThread.start();
26         Thread.sleep(3000);
27         System.out.println("Interrupt thread...: " + interruptThread.getName());
28         // 设置退出标识为true
29         interruptThread.exit = true;
30         interruptThread.interrupt();
31         // 主线程休眠3秒以便观察线程interruptThread的中断情况
32         Thread.sleep(3000);
33         System.out.println("Stopping application...");
34     }
35 }

若第30行注释,则在运行到第12行交出子线程InterruptThread的CPU使用权后,主线程执行完毕,此时便会阻塞子线程;导致29行的标识无用。

此中情况只需要主动的中断线程即可(第30行代码)。

public class InterruptThread extends Thread {
/**
* 退出标识
*/
volatile boolean exit = false;

@Override
public void run() {
while (!exit) {
System.out.println(getName() + " is running");
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
System.out.println("week up from block...");
// 在异常处理代码中修改共享变量的状态
exit = true;
}
}
System.out.println(getName() + " is exiting...");
}

public static void main(String[] args) throws InterruptedException {
InterruptThread interruptThread = new InterruptThread();
System.out.println("Starting thread...");
interruptThread.start();
Thread.sleep(3000);
System.out.println("Interrupt thread...: " + interruptThread.getName());
// 设置退出标识为true
interruptThread.exit = true;
interruptThread.interrupt();
// 主线程休眠3秒以便观察线程interruptThread的中断情况
Thread.sleep(3000);
System.out.println("Stopping application...");
}
}

猜你喜欢

转载自www.cnblogs.com/bzfsdr/p/11565280.html