java多线程之停止线程

Wesley13
• 阅读 617

在多线程开发中停止线程是很重要的技术点。停止线程在Java语言中并不像break语句那样干脆,需要一些技巧性的处理。

一、  异常法

采用异常法来停止一个线程,首先我们需要了解一下两个方法的用法:

1、interrupt()方法

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <= 10000; i++) {
            System.out.println("i="+i);
        }
    }
    public static void main(String[] args)throws Exception {
        MyThread thread=new MyThread();
        thread.start();
        thread.sleep(10);
        thread.interrupt();
    }
}

上面的例子调用interrupt()方法来停止线程,但interrupt()方法的使用效果并不像for+break语句那样,马上就能停止循环。调用interrupt()方法仅仅是在当前线程打了一个停止的标记,并不是真的停止。那么如果停止线程了?我们接着往下面看。

2、判断线程是否是停止状态

1)、  interrupted()

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <= 10000; i++) {
            System.out.println("i="+i);
        }
    }
    public static void main(String[] args)throws Exception {
        try{
            MyThread thread=new MyThread();
            thread.start();
            thread.sleep(100);
            thread.interrupt();
            System.out.println("线程停止了吗1?--->"+thread.interrupted());
            System.out.println("线程停止了吗2?--->"+thread.interrupted());
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("end");
        
    }
}

java多线程之停止线程
从控制台打印的结果来看,线程没有停止,这就是说,interrupted()测试当前线程是否中断,因为这个当前线程就是main,它没有中断过,所以打印的结果是两个false。

如何使main线程产生中断效果了。我们在看下,下面的例子:

public class MyThread{
    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");
    }
}

java多线程之停止线程

从上面的结果来看,interrupted()方法的确判断当前线程是否是停止状态。但是为什么第2个值是false。原来,连续两次调用该方法第一次会清除中断状态后,第二次调用所以返回flase。

2)、  isInterrupted()

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <= 10000; i++) {
            System.out.println("i="+i);
        }
    }
    public static void main(String[] args){
        try{
            MyThread thread=new MyThread();
            thread.start();
            thread.sleep(10);
            thread.interrupt();
            System.out.println("线程停止了吗1?--->"+thread.isInterrupted());
            System.out.println("线程停止了吗2?--->"+thread.isInterrupted());
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("end");
        
    }
}

java多线程之停止线程

从结果看出方法isInterrupted()并未清除,所以打印出了两个true.

3、停止线程

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <= 10000; i++) {
            if(this.interrupted()){
                System.out.println("线程是停止状态了,我要退出了.");
                break;
            }
            System.out.println("i="+i);
        }
        System.out.println("如果此处还是循环,那么我就会继续执行.线程并没有停止");
    }
    public static void main(String[] args){
        try{
            MyThread thread=new MyThread();
            thread.start();
            thread.sleep(10);
            thread.interrupt();
            System.out.println("end");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

java多线程之停止线程

如果这么写的话,线程并没有停止。现在我们在修改下代码,也就是所谓的异常法停止线程。

public class MyThread extends Thread{
    @Override
    public void run() {
        try{
            for (int i = 1; i <= 10000; i++) {
                if(this.interrupted()){
                    System.out.println("线程是停止状态了,我要退出了.");
                    throw new InterruptedException();
                }
                System.out.println("i="+i);
            }
            System.out.println("我被执行了吗?");
        }catch(InterruptedException e){
            System.out.println("---这次线程停了---");
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        try{
            MyThread thread=new MyThread();
            thread.start();
            thread.sleep(10);
            thread.interrupt();
            System.out.println("end");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

java多线程之停止线程

二、  在沉睡中停止

如果线程在sleep()状态下停止线程会有什么效果了?

public class MyThread extends Thread{
    @Override
    public void run() {
        try{
            System.out.println("run start");
            Thread.sleep(1000000);
            System.out.println("run end");
        }catch(InterruptedException e){
            System.out.println("sleep被停止,状态:--->"+this.isInterrupted());
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        try{
            MyThread thread=new MyThread();
            thread.start();
            thread.interrupt();
            thread.sleep(1000);
        }catch(Exception e){
            System.out.println("main catch");
            e.printStackTrace();
        }
    }
}

java多线程之停止线程

从结果我们可以看出,在线程睡眠时候停止某一线程,会异常,并且清除停止状态。我们前面异常停止线程,都是先睡眠,在停止线程,与之相反的操作,我写代码的时候需要注意下。

public class MyThread extends Thread{
    @Override
    public void run() {
        try{
            for (int i = 1; i <= 10000; i++) {
                System.out.println("i="+i);
            }
            System.out.println("run start");
            Thread.sleep(1000000);
            System.out.println("run end");
        }catch(InterruptedException e){
            System.out.println("线程被停止了,在sleep,状态:--->"+this.isInterrupted());
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        try{
            MyThread thread=new MyThread();
            thread.start();
            thread.interrupt();
        }catch(Exception e){
            System.out.println("main catch");
            e.printStackTrace();
        }
    }
}

java多线程之停止线程

三、  暴力停止

public class MyThread extends Thread{
    private int i=0;
    @Override
    public void run() {
        try{
            while (true) {
                i++;
                System.out.println("i="+i);
                Thread.sleep(1000);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        try{
            MyThread thread=new MyThread();
            thread.start();
            Thread.sleep(6000);
            thread.stop();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

java多线程之停止线程

stop()方法已经被弃用,如果强制让线程停止,可以会有一些清理工作没得到完成,还有就是对锁定的对象进行了解锁,导致数据不同步的现象,所以开发时候禁止使用该方法去暴力停止线程。

四、  使用return停止线程

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

java多线程之停止线程

PS:不过还是建议使用异常法来停止线程,因为在catch块中还可以将异常向上抛,使线程停止事件得到传播。

版权声明:本文为博主原创文章,未经博主允许不得转载。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
御弟哥哥 御弟哥哥
3年前
如何正确停止Java线程,终止Java线程的三种方法
如何正确停止Java线程,终止Java线程的三种方法在Java中有以下3种方法可以终止正在运行的线程:1.使用退出标志,使线程正常退出,也就是当run()方法完成后线程终止。2.使用stop()方法强行终止线程,但不推荐,该方法已被弃用,原因见后文。3.使用interrupt方法中断线程。以下内容翻译自J
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
03.Android崩溃Crash库之ExceptionHandler分析
目录总结00.异常处理几个常用api01.UncaughtExceptionHandler02.Java线程处理异常分析03.Android中线程处理异常分析04.为何使用setDefaultUncaughtExceptionHandler前沿上一篇整体介绍了crash崩溃
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Java多线程9:中断机制
一、概述  之前讲解Thread类中方法的时候,interrupt()、interrupted()、isInterrupted()三个方法没有讲得很清楚,只是提了一下。现在把这三个方法同一放到这里来讲,因为这三个方法都涉及到多线程的一个知识点中断机制。  Java没有提供一种安全、直接的方法来停止某个线程,而是提供了中断机制。中
Wesley13 Wesley13
3年前
Java线程停止方法之Interrupt方法
  最近在学习Java多线程相关的知识点,其中关于线程停止的方法网上也有不少大牛给出了详细的解答,而我这边就其中Interrupt方法的注意点给自己提个醒。  首先还是大概的罗列下停止线程的方法:  1、使用stop()方法等,不过已经不再被推荐使用,和suspend、resume一样。  2、使用退出标志终止线程,引入一个共享变量,volati