赞
踩
Java 中有以3 种方法可以中断正在运行的线程:
定义一个boolean型的标志位,在线程的run方法中根据这个标志位是true还是false来判断是否退出
- /**
- * 使用标志位终止线程
- * */
- public class ThreadStop {
- public static void main(String[] args) {
- ThreadStopRunnable runnable = new ThreadStopRunnable();
- Thread t = new Thread(runnable);
- t.setName("t");
- t.start();
-
- try {
- Thread.sleep(1000 * 5);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- //执行5秒之后终止线程,终止t线程的执行,将标记修改为false即可
- runnable.runFlag = false;
-
- System.out.println(Thread.currentThread().getName() + "\t" + "main is over");
- }
- }
-
- class ThreadStopRunnable implements Runnable {
- //volatile修饰符用来保证其它线程读取的总是该变量的最新的值
- public volatile boolean runFlag = true;
-
- @Override
- public void run() {
- for (int i = 1; i <= 100; i++) {
- if (runFlag){
- System.out.println(Thread.currentThread().getName() + "---->" + i);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }else {
- //执行终止线程之前的代码,如保存数据等
-
- return;
- }
- }
- }
- }
可以使用AtomicBoolean作为标记位,省去volatile关键字修饰。
- /**
- * 使用标志位终止线程
- * */
- public class ThreadStop {
- public static void main(String[] args) {
- ThreadStopRunnable runnable = new ThreadStopRunnable();
- Thread t = new Thread(runnable);
- t.setName("t");
- t.start();
-
- try {
- Thread.sleep(1000 * 5);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- //执行5秒之后终止线程,终止t线程的执行,将标记修改为false即可
- runnable.runFlag.set(false);
-
- System.out.println(Thread.currentThread().getName() + "\t" + "main is over");
- }
- }
-
- class ThreadStopRunnable implements Runnable {
- //volatile修饰符用来保证其它线程读取的总是该变量的最新的值
- public AtomicBoolean runFlag = new AtomicBoolean(true);
-
- @Override
- public void run() {
- for (int i = 1; i <= 100; i++) {
- if (runFlag.get()){
- System.out.println(Thread.currentThread().getName() + "---->" + i);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }else {
- //执行终止线程之前的代码,如保存数据等
-
- return;
- }
- }
- }
- }
使用interrupt()方法,仅仅是给线程打上中断标记位,并没有实际中断线程(把中断的权利交给线程本身,更安全)
interrupt() 正在睡眠的线程会抛出InterruptedException异常。
- /**
- * 使用标志位终止线程
- * */
- public class ThreadStop {
- public static void main(String[] args) {
- ThreadStopRunnable runnable = new ThreadStopRunnable();
- Thread t = new Thread(runnable);
- t.setName("t");
- t.start();
-
- try {
- Thread.sleep(1000 * 5);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- t.interrupt();
- System.out.println(Thread.currentThread().getName() + "\t" + "main is over");
- }
- }
-
- class ThreadStopRunnable implements Runnable {
-
- @Override
- public void run() {
- for (int i = 1; i <= 100; i++) {
- if (!Thread.currentThread().isInterrupted()){
- System.out.println(Thread.currentThread().getName() + "---->" + i);
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- e.printStackTrace();
- }
- }else {
- //执行终止线程之前的代码,如保存数据等
-
- return;
- }
- }
- }
- }
t---->1
t---->2
t---->3
t---->4
t---->5
main main is over
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at org.mark.spring.test.ThreadStopRunnable.run(ThreadStop.java:35)
at java.lang.Thread.run(Thread.java:748)
通过查看 JDK 的 API,我们会看到 java.lang.Thread 类型提供了一系列的方法如 start()、stop()、resume()、suspend()、destory()等方法来管理线程。但是除了 start() 之外,其它方法都被声名为已过时(deprecated)
虽然 stop() 方法确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且该方法已被弃用,最好不要使用它。
JDK 文档中还引入用一篇文章来解释了弃用这些方法的原因:《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?》
为何弃用stop:
1、调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭
2、调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。