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;造成污染。

看下面的代码示例。

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();
        }
    }
}

 

ZPY

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: