一、停止线程的几种方法
- 使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程中止。
- 使用interrupt()方法中断线程。
- 使用stop()方法强行终止线程,但是不推荐使用这个方法,该方法已被弃用!!!
二、方法详解
使用标志位终止线程
/** * 设置标识位停止线程 */ public class MyThreadStop { //计数 private static int count = 0; //退出标识符 public static boolean exit = false; /** * 核心线程 */ public static void main(final String[] arguments) throws InterruptedException { Thread t = new Thread(new TestThread()); t.start(); } /** * 同步方法 */ public static synchronized void countNum() { for (int i = 0; i < 100000; i++) { if (count >= 500000) { exit = true; //修改标志位,退出线程 } else { count++; System.out.println(count); } } } /** * 线程实体(实现Runnable接口) */ static class TestThread implements Runnable { public void run() { while (!exit) {//当标识符没设置停止时,一直做参数递增 countNum(); } } } }
使用interrupt()方法中断线程
- interrupt() 方法并不像在 for 循环语句中使用 break 语句那样干脆,马上就停止循环。
- 调用 interrupt() 方法仅仅是在当前线程中打一个停止的标记,并不会立即终止线程。
- 至于目标线程收到通知后会如何处理,则完全由目标线程自行决定。
/** * interrupt()方法停止线程 */ public class MyThreadStop { //计数器 private static int count = 0; /** * 核心线程 */ public static void main(final String[] arguments) throws InterruptedException { Thread t = new Thread(new TestThread()); t.start(); //休眠一会儿,然后中断 t.sleep(200); t.interrupt(); } /** * 同步方法 */ public static synchronized void countNum() { for (int i = 0; i < 500000; i++) { count++; System.out.println(count); } } /** * 线程实体(实现Runnable接口) */ static class TestThread implements Runnable { public void run() { countNum(); } } }
上面的例子我们发现,好像interrupt方法并没有马上停止线程,还是继续跑完了,这是由于interrupt() 方法仅仅是在当前线程中打一个停止的标记,并不会立即终止线程。 至于目标线程收到通知后会如何处理,则完全由目标线程自行决定。
我们可以改造一下~
/** * interrupt()方法停止线程 */ public class MyThreadStop { //计数器 private static int count = 0; /** * 核心线程 */ public static void main(final String[] arguments) throws InterruptedException { Thread t = new Thread(new TestThread()); t.start(); //休眠一会儿,然后中断 t.sleep(200); t.interrupt(); } /** * 线程实体(实现Runnable接口) */ static class TestThread implements Runnable { public void run() { for (int i = 0; i < 500000; i++) { //判断线程是否被通知中断 if (Thread.currentThread().isInterrupted()) { //处理中断逻辑 break; } count++; System.out.println(count); } } } }
可以发现,在加入中断判断以后,线程停止了工作
PS:当线程被 sleep() 休眠时,如果被中断,就会抛出一个 InterruptedException异常。
PS:Thread.sleep() 方法由于中断而抛出的异常,是会清除中断标记的,线程后面的代码会继续执行。
stop()方法
stop()方法停止线程的方式相当粗暴,直接停止线程工作,相当不安全,虽然现在已经弃用,还是简单的了解一下吧。
为什么弃用stop:
- 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
- 调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。
好文推荐: