- A+
所属分类:Java多线程
在java多线程里,启动一个线程很简单,那就是start,但是要停止一个线程就没那么简单了。首先想到的肯定是stop,但是很遗憾,stop方法已经被废弃,因为用stop是强制让线程停止,可能使一些清理性工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。
那么,正确的停止线程的方法是什么呢?答案是用interrupted方法。但是,请注意,interrupted方法并不会立即停止线程,而是仅仅给线程打了一个停止的标记,并不是真正停止线程。这个标记有什么用呢?这个标记是在线程里自己判断用的,也就是说,用这种方式停止线程,还要在线程线程里用this.interrupted()方法判断是否为停止标志,是的话则用抛出异常或者return两种方式来停止。
另外有一点需要注意的是,判断是否停止的方法有两种,this.interrupted()和this.isInterrupted()。这两个方法都是判断是否当前线程是否停止,区别是this.interrupted()执行后会具有将状态标志清除为false的功能,this.isInterrupted()则不会。
总的来说,用抛出异常的方式比用return的方式来停止线程要好。因为在catch块中可以对异常的信息进行相关的处理,而且使用异常流能更好,更方便的控制程序的运行流程,不至于代码中出现很多个return;造成污染。
看下面的代码示例。
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { System.out.println(System.currentTimeMillis() + " i= "+i); } } }
public class MyThread2 extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { if (this.isInterrupted()) { // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,break手动停止。 System.out.println("已中止"); break; } System.out.println(System.currentTimeMillis() + " i= "+i); } System.out.println("for下面被执行"); } }
public class MyThread3 extends Thread { @Override public void run() { super.run(); try { for (int i = 0; i < 500000; i++) { if (this.isInterrupted()) { // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,一般用异常的方式来停止。 // 使用异常方法来停止比用return好 System.out.println("已中止"); throw new InterruptedException(); } System.out.println(System.currentTimeMillis() + " i= " + i); } System.out.println("for下面被执行"); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class MyThread4 extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { if (this.isInterrupted()) { // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,return也能停止。 System.out.println("已中止"); return; } System.out.println(System.currentTimeMillis() + " i= "+i); } System.out.println("for下面被执行"); } }
public class Main { public static void main(String[] args) { // 停止线程不推荐用stop,stop是暴力停止,可能会带来数据不一致的问题。 // MyThread myThread = new MyThread(); // MyThread2 myThread = new MyThread2(); // MyThread3 myThread = new MyThread3(); MyThread4 myThread = new MyThread4(); myThread.start(); try { Thread.sleep(2000); myThread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }