Java多线程总结之(一)停止线程

  • A+
所属分类:Java多线程

在java多线程里,启动一个线程很简单,那就是start,但是要停止一个线程就没那么简单了。首先想到的肯定是stop,但是很遗憾,stop方法已经被废弃,因为用stop是强制让线程停止,可能使一些清理性工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。

那么,正确的停止线程的方法是什么呢?答案是用interrupted方法。但是,请注意,interrupted方法并不会立即停止线程,而是仅仅给线程打了一个停止的标记,并不是真正停止线程。这个标记有什么用呢?这个标记是在线程里自己判断用的,也就是说,用这种方式停止线程,还要在线程线程里用this.interrupted()方法判断是否为停止标志,是的话则用抛出异常或者return两种方式来停止。

另外有一点需要注意的是,判断是否停止的方法有两种,this.interrupted()和this.isInterrupted()。这两个方法都是判断是否当前线程是否停止,区别是this.interrupted()执行后会具有将状态标志清除为false的功能,this.isInterrupted()则不会。

总的来说,用抛出异常的方式比用return的方式来停止线程要好。因为在catch块中可以对异常的信息进行相关的处理,而且使用异常流能更好,更方便的控制程序的运行流程,不至于代码中出现很多个return;造成污染。

看下面的代码示例。

  1. public class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. super.run();
  5. for (int i = 0; i < 500000; i++) {
  6. System.out.println(System.currentTimeMillis() + " i= "+i);
  7. }
  8. }
  9. }
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);
        }
    }
}

 

  1. public class MyThread2 extends Thread {
  2. @Override
  3. public void run() {
  4. super.run();
  5. for (int i = 0; i < 500000; i++) {
  6. if (this.isInterrupted()) {
  7. // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,break手动停止。
  8. System.out.println("已中止");
  9. break;
  10. }
  11. System.out.println(System.currentTimeMillis() + " i= "+i);
  12. }
  13. System.out.println("for下面被执行");
  14. }
  15. }
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下面被执行");
    }
}

 

  1. public class MyThread3 extends Thread {
  2. @Override
  3. public void run() {
  4. super.run();
  5. try {
  6. for (int i = 0; i < 500000; i++) {
  7. if (this.isInterrupted()) {
  8. // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,一般用异常的方式来停止。
  9. // 使用异常方法来停止比用return好
  10. System.out.println("已中止");
  11. throw new InterruptedException();
  12. }
  13. System.out.println(System.currentTimeMillis() + " i= " + i);
  14. }
  15. System.out.println("for下面被执行");
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }
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();
        }
    }
}

 

 
  1. public class MyThread4 extends Thread {
  2. @Override
  3. public void run() {
  4. super.run();
  5. for (int i = 0; i < 500000; i++) {
  6. if (this.isInterrupted()) {
  7. // 使用interrupt并未真正停止一个线程,而是给一个停止的标识,需要判断,return也能停止。
  8. System.out.println("已中止");
  9. return;
  10. }
  11. System.out.println(System.currentTimeMillis() + " i= "+i);
  12. }
  13. System.out.println("for下面被执行");
  14. }
  15. }
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下面被执行");
    }
}

 

  1. public class Main {
  2. public static void main(String[] args) {
  3. // 停止线程不推荐用stop,stop是暴力停止,可能会带来数据不一致的问题。
  4. // MyThread myThread = new MyThread();
  5. // MyThread2 myThread = new MyThread2();
  6. // MyThread3 myThread = new MyThread3();
  7. MyThread4 myThread = new MyThread4();
  8. myThread.start();
  9. try {
  10. Thread.sleep(2000);
  11. myThread.interrupt();
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. }
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();
        }
    }
}