zoukankan      html  css  js  c++  java
  • java多线程系列7-停止线程

    本文主要总结在java中停止线程的方法

    在java中有以下三种方法可以终止正在运行的线程:

    1、使用退出标志

    2、使用stop方法强行终止线程,但是不推荐,因为stop和suspend、resume一样都是过时的方法

    3、使用interrup方法中断线程

    停止不了的线程

    本例将使用interrupt方法来停止进程,看看效果:

    public class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            for (int i = 0; i < 1234; i++) {
                System.out.println("i=" + (i + 1));
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(2000);
                thread.interrupt();
                
                
            } catch (InterruptedException e) {
                System.out.println("main catch");
                e.printStackTrace();
            }
        }
    }

    可以看出,线程没有停止

    判断线程是否是停止状态

    在java的SDK中,Thread.java类里提供了两种方法:

    (1)this.interrupted():测试当前线程是否已经中断

    (2)this.isInterrupted():测试线程是否已经中断

    首先看一下interrupted()

    实战验证一下:

    public class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            for (int i = 0; i < 10000; i++) {
                System.out.println("i=" + (i + 1));
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(1000);
                thread.interrupt();
                System.out.println("是否停止1?="+thread.interrupted());
                System.out.println("是否停止2?="+thread.interrupted());
                
                
            } catch (InterruptedException e) {
                System.out.println("main catch");
                e.printStackTrace();
            }
            System.out.println("end!");
        }
    }

    运行结果如下:

    .......................

    i=9998
    i=9999
    i=10000
    是否停止1?=false
    是否停止2?=false
    end!

    由于interrupted是测试当前线程,当前线程为main,一直没有中断,所以返回两个false

    将代码修改一下:

    public class Run {
        public static void main(String[] args) {
            Thread.currentThread().interrupt();
            System.out.println("是否停止1?=" + Thread.interrupted());
            System.out.println("是否停止2?=" + Thread.interrupted());
            System.out.println("end!");
        }
    }

    返回如下信息:

    是否停止1?=true
    是否停止2?=false
    end!

    由于interrupted方法有清除状态的功能,所以第二次返回false

    再看看isInterrupted()方法

    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(1000);
                thread.interrupt();
                System.out.println("是否停止1?=" + thread.isInterrupted());
                System.out.println("是否停止2?=" + thread.isInterrupted());
     
            } catch (InterruptedException e) {
                System.out.println("main catch");
                e.printStackTrace();
            }
            System.out.println("end!");
        }
    }

    运行结果:

    i=123367
    i=123368
    是否停止1?=true
    是否停止2?=true
    i=123369
    i=123370
    i=123371
    i=123372

    总结:

    (1)this.interrupted():测试当前线程是否已经中断,执行后具有将状态标志清除为false的功能

    (2)this.isInterrupted():测试线程是否已经中断,但不清除状态标志

    能停止的线程--异常法

    可以在线程中用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("已经是停止状态了,我要退出了!");
                        throw new InterruptedException();
                    }
                    System.out.println("i=" + (i + 1));
                }
                System.out.println("我在for下面");
            } catch (InterruptedException e) {
                System.out.println("进MyThread.java类run方法中的catch了!");
                e.printStackTrace();
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(2000);
                thread.interrupt();
            } catch (InterruptedException e) {
                System.out.println("main catch");
                e.printStackTrace();
            }
            System.out.println("end!");
        }
    }

    在sleep中停止

    如果线程在sleep状态下停止线程,有什么效果呢?

    public class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                System.out.println("run begin");
                Thread.sleep(200000);
                System.out.println("run end");
            } catch (InterruptedException e) {
                System.out.println("在沉睡中被停止!进入catch!" + this.isInterrupted());
                e.printStackTrace();
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(200);
                thread.interrupt();
            } catch (InterruptedException e) {
                System.out.println("main catch");
                e.printStackTrace();
            }
            System.out.println("end!");
        }
    }

    运行结果:

    run begin
    end!
    在沉睡中被停止!进入catch!false
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.wuyudong.test1.MyThread.run(MyThread.java:9)

    结果说明如果在sleep状态下停止线程,会进入catch语句,并且清除停止状态值,使之变成false

    下面进行相反的操作,修改一下:

    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("run begin");
                Thread.sleep(200000);
                System.out.println("run end");
            } catch (InterruptedException e) {
                System.out.println("先停止,再遇到了sleep!进入catch!");
                e.printStackTrace();
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            MyThread thread = new MyThread();
            thread.start();
            thread.interrupt();
            System.out.println("end!");
        }
    }

    运行结果如下:

    i=100000
    run begin
    先停止,再遇到了sleep!进入catch!
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.wuyudong.test1.MyThread.run(MyThread.java:12)

    能停止的线程--暴力停止

    使用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 (InterruptedException e) {
                System.out.println("先停止,再遇到了sleep!进入catch!");
                e.printStackTrace();
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(8000);
                thread.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    运行结果如下:

    i=1
    i=2
    i=3
    i=4
    i=5
    i=6
    i=7
    i=8

    方法stop与异常

    调用stop方法的时候会抛出java.lang.ThreadDeath异常,但是通常此异常不需要显式地捕捉

    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 (InterruptedException e) {
                System.out.println("先停止,再遇到了sleep!进入catch!");
                e.printStackTrace();
            }
        }
    }
    public class Run {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(8000);
                thread.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    使用return停止线程

    将方法interrupt与return结合使用也能实现停止线程的效果

    public class MyThread extends Thread {
        private int i = 0;
        @Override
        public void run() {
            super.run();
            while(true){
                if(this.isInterrupted()){
                    System.out.println("停止了!");
                    return;
                }
                System.out.println("timer="+System.currentTimeMillis());
            }
        }
    }
    public class Run {
        public static void main(String[] args) throws InterruptedException{
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(2000);
                thread.interrupt();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    运行结果如下:

    timer=1452841019023
    timer=1452841019023
    timer=1452841019023
    timer=1452841019023
    停止了!

  • 相关阅读:
    三角洲
    苏州
    苏州
    Java EE (4) -- Java EE 6 Java Persistence API Developer Certified Expert(1z0-898)
    快排,堆排
    P1427 小鱼的数字游戏 洛谷
    P1093||T1142 奖学金 洛谷||codevs
    家谱树 拓扑排序【模板】
    P1918 保龄球 洛谷
    P1359 租用游艇 洛谷
  • 原文地址:https://www.cnblogs.com/wuyudong/p/java-multithreading7.html
Copyright © 2011-2022 走看看