多线程学习(四)

在Java中有三种方法用于中止线程:java

    1 . 使用退出标识,使线程正常退出, 也就是当run()方法完成后终止线程.ide

    2 . 使用stop()方法强制中止线程, 可是不推荐这种方法, 由于stop和suspend , resume方法同样, 都是做废过时的方法, 使用这相似的方法可能致使不可预期的错误.测试

    3 . 使用interrupt方法终止线程.this

 

一 . interrupt()spa

    下述代码将使用interrupt()方法进行中止线程,可是interrupt()方法的使用效果并不像for循环中的break同样,立刻就中止循环. 调用interrupt()方法仅仅是在当前线程中打了一个中止的标记,并非真正的中止线程.因此在使用interrupt()方法的时候还须要加入一个判断才能够完成线程的中止.线程

    

    代码段:对象

public class MyThread extends Thread {
    
        @Override
        public void run() {
            super.run();
            for (int i = 0; i < 500000; i++) {
                System.out.println("i = " + (i + 1));
            }
        }
    
    }

    运行类:get

public class Test {
        public static void main(String[] args) {
            try{
                MyThread myThread = new MyThread();
                Thread thread = new Thread(myThread);
                thread.start();
                Thread.sleep(1000);
                thread.interrupt();
            }catch (Exception e){
                e.printStackTrace();
            }
    
        }
    }

运行结果:同步

    

    从运行结果能够看出,interrupt()方法并无将当前线程中止.io

二 . 判断线程是否中止

        Java中Thread.java类中提供了两种方法进行判断线程是否中止的判断

        1 . interrupted()

             测试当前线程是否已经中断(会清除线程中断状态)

             测试当前线程是不是中断状态,执行后具备将状态标识清除为false的功能.

        2 . isInterrupted()

             测试线程Thread对象是否已是中断状态,但不提供清除状态标识为false的功能.

 

三 . 中止线程(异常中止)

public class MyThread extends Thread {

            @Override
            public void run() {
                super.run();
                for (int i = 0; i < 500000; i++) {
                    if (this.interrupted()) {
                        System.out.println("Thread interrupted.");
                        break;
                    }
                    System.out.println("i = " + (i + 1));
                }
                System.out.println("end.");
            }

        }
public class Test {
            public static void main(String[] args) {
                try {
                    MyThread myThread = new MyThread();
                    myThread.start();
                    myThread.setName("test");
                    Thread.sleep(1000);
                    myThread.interrupt();
                    System.out.println("线程名字 :" + myThread.getName());
                    System.out.println("线程是否中断 : " + myThread.interrupted());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }

    运行结果:

使用这种方法将线程中止后for循环后面的代码还会继续运行, 若是for循环后面还存在一个或多个for循环,则该线程并不会结束.

 

因此,将第一段代码进行修改:

public class MyThread extends Thread {

    @Override
    public void run() {
        super.run();
        try {
            for (int i = 0; i < 500000; i++) {
                if (this.interrupted()) {
                    System.out.println("Thread interrupted.");
                    throw new InterruptedException();
                }
                System.out.println("i = " + (i + 1));
            }
            System.out.println("end.");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

    运行结果:

    

由两次运行结果能够看出for循环后面的end没有输出.

 

四 . 中止线程(睡眠中止)

       先中止,在进入sleep

public class MyThread extends Thread {

    @Override
    public void run() {
        super.run();
        try {
            for(int i = 0 ; i < 100000 ; i ++){
                System.out.println(" i = " + (i + 1));
            }
            System.out.println("Thread run begin");
            Thread.sleep(200000);
            System.out.println("Thread run end");
        }catch (Exception e){
            System.out.println("end in sleep ." + this.interrupted());
            e.printStackTrace();
        }
    }

}
public class Test {
    public static void main(String[] args) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            myThread.setName("test");
            myThread.interrupt();
            System.out.println("线程名字 :" + myThread.getName());
            System.out.println("线程是否中断 : " + myThread.interrupted());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果:

注:若是先进入sleep,在中止线程,会进入catch语句,而且清除状态值,使之变为false.

     先中止在进入sleep,也会进入catch,可是不会清除状态值.

五 . 暴力中止

      暴力中止即直接使用stop()方法    

public class MyThread extends Thread {

            private int i = 0 ;
            @Override
            public void run() {
                super.run();
                try {
                    while(true){
                        i ++;
                        System.out.println(" i = " + i );
                        Thread.sleep(1000);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

        }

        

public class Test {
            public static void main(String[] args) {
                try {
                    MyThread myThread = new MyThread();
                    myThread.start();
                    myThread.setName("test");
                    Thread.sleep(8000);
                    myThread.stop();
                    System.out.println("线程名字 :" + myThread.getName());
                    System.out.println("线程是否中断 : " + myThread.interrupted());
                } catch (Exception e) {
                    e.printStackTrace();
                }
        
            }
        }

    运行结果:

    

 

        注 : 方法stop和java.lang.ThreadDeath异常

              在调用stop()方法时,会抛出java.lang.ThreadDeath异常,可是通常状况下不须要特地去捕获该异常 

              方法stop()已经做废了,由于若是强制让线程中止则有可能使一些清理性的工做没法完成,另一种状况就是对锁定的对象进行了解锁,致使数据得不到同步的处理,出现数据不一致的问题.

 

六 .  释放锁的不良影响

        使用stop()方法中止线程释放锁之后会给数据形成不一致的结果,若是出现这样的状况,程序处理的数据就有可能遭到破坏,最终致使程序执行的流程出错.

public class Start {
    private String a = "a";
    private String b = "b";

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    synchronized public void printString(String username , String pswd){
        try{
            a = username;
            Thread.sleep(1000);
            b = pswd;
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

public class MyThread extends Thread {

    private Start start;

    public MyThread(Start startObject){
        super();
        start = startObject;
    }

    @Override
    public void run(){
        start.printString("b","bb");
    }
}
public class Test {
    public static void main(String[] args) {
        try {
            Start start = new Start();
            MyThread myThread = new MyThread(start);
            myThread.start();
            Thread.sleep(500);
            myThread.stop();
            System.out.println("name = " + start.getA() + " ; password = " + start.getB());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果:

    

因为stop()方法已经在JDK中呗标记为做废的方法,因此他在功能上具备缺陷,尽可能不要在程序中使用.

 

七 .  使用return中止线程

        将方法interrupt()和return结合使线程中止.

public class MyThread extends Thread {

    @Override
    public void run(){
        while(true){
            if(this.isInterrupted()){
                System.out.println("Thread ended.");
                return;
            }
            System.out.println("time = " + System.currentTimeMillis());
        }
    }
}
public class Test {
    public static void main(String[] args) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            Thread.sleep(2000);
            myThread.interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果:

 

虽然有多种方法使线程中止,可是仍是建议经过catch语句块中止线程,由于catch语句块能够抛出异常到上层.

相关文章
相关标签/搜索