Thread类中有start(), stop()方法,不过stop方法已经被废弃掉。

平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程

如果有阻塞,需要使用Thread的interrupt()方中断阻塞,线程开始检查标志(PS:抛出异常不会退出循环)

------------------------------------------------------------我是copy分割线----------------------------------------------

原出处:http://blog.163.com/xh_ding/blog/static/193903289201341685931689

如何停止java的线程一直是一个开发多线程程序常遇到的一个问题。也有好多人问过我,所以今天在这里总结一下希望可以让更多的人知道在java中如何安全的结束一个正在运行的线程。

在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。

在JDK帮助文档以及Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中都讲解了舍弃这些方法的原因。
那么,我们究竟应该如何停止线程呢?这里我们介绍两种方法:
 
1. 使用共享变量的方式

在这种方式中,之所以引入共享变量,是因为该变量可以被多个执行相同任务的线程用来作为是否中断的信号,通知中断线程的执行。

 
public class ThreadFlag extends Thread 
    public volatile boolean exit = false; 
 
    public void run() 
    { 
        while (!exit); 
    } 
    public static void main(String[] args) throws Exception 
    { 
        ThreadFlag thread = new ThreadFlag(); 
        thread.start(); 
        sleep(3000); // 主线程延迟3秒 
        thread.exit = true;  // 终止线程thread 
        thread.join(); 
        System.out.println("线程退出!"); 
    } 
在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false。在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值。
 
  private volatile Thread blinker; 
    public void stop() { 
        blinker = null; 
    } 
    public void run() { 
        Thread thisThread = Thread.currentThread(); 
        while (blinker == thisThread) { 
            try { 
                thisThread.sleep(interval); 
            } catch (InterruptedException e){ 
            } 
            repaint(); 
        } 
    }
 
2.  使用interrupt方法终止线程 
 
如果一个线程由于等待某些事件的发生而被阻塞,又该怎样停止该线程呢?这种情况经常会发生,比如当一个线程由于需要等候键盘输入而被阻塞,或者调用Thread.join()方法,或者Thread.sleep()方法,在网络中调用ServerSocket.accept()方法,或者调用了DatagramSocket.receive()方法时,都有可能导致线程阻塞,使线程处于处于不可运行状态时,即使主程序中将该线程的共享变量设置为true,但该线程此时根本无法检查循环标志,当然也就无法立即中断。这里我们给出的建议是,不要使用stop()方法,而是使用Thread提供的interrupt()方法,因为该方法虽然不会中断一个正在运行的线程,但是它可以使一个被阻塞的线程抛出一个中断异常,从而使线程提前结束阻塞状态,退出堵塞代码。
 
class MyThread extends Thread {
volatile boolean stop = false;
 
public void run() {
while (!stop) {
System.out.println(getName() + " is running");
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println("week up from blcok...");
stop = true; // 在异常处理代码中修改共享变量的状态
}
}
System.out.println(getName() + " is exiting...");
}
}
 
class InterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = new MyThread();
System.out.println("Starting thread...");
m1.start();
Thread.sleep(3000);
System.out.println("Interrupt thread...: " + m1.getName());
m1.stop = true; // 设置共享变量为true
m1.interrupt(); // 阻塞时退出阻塞状态
Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断情况
System.out.println("Stopping application...");
}
}
 
注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。

java如何正确停止一个线程的更多相关文章

  1. Java 如何正确停止一个线程

    自己在做实验性小项目的时候,发现自己遇到一个问题:如何控制线程的"死亡"? 首先,如何开启一个线程呢? 最简单的代码: public class Main { public sta ...

  2. Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程

    下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...

  3. Java并发(基础知识)—— 创建、运行以及停止一个线程

    在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行.如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的:如果计算机只有一个核心处理器那么就只是表面现象. 现代所有的 ...

  4. Java再学习——停止一个正在运行的线程

    关于这个问题,先了解一下Thread类方法中被废弃的那些方法.suspend(), resume(),stop()/stop(Throwable obj),destroy() 首先,stop(Thro ...

  5. java停止一个线程

    Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...

  6. 别指望一文读懂Java并发之从一个线程开始

    Understanding concurrent programming is on the same order of difficulty as understanding object-orie ...

  7. java holdsLock()方法检测一个线程是否拥有锁

    http://blog.csdn.net/w410589502/article/details/54949506 java.lang.Thread中有一个方法叫holdsLock(),它返回true如 ...

  8. JAVA多线程之当一个线程在执行死循环时会影响另外一个线程吗?

    一,问题描述 假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗? 二,示例代码(代码 ...

  9. Java自学-多线程 启动一个线程

    Java 创建一个线程的三种方式 多线程即在同一时间,可以做多件事情. 创建多线程有3种方式,分别是继承线程类,实现Runnable接口,匿名类 步骤 1 : 线程概念 首先要理解进程(Process ...

随机推荐

  1. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  2. 「PKUSC2018」最大前缀和(状压dp)

    前言 考试被\(hyj\)吊着打... Solution 考虑一下如果前缀和如果在某一个位置的后面的任意一个前缀和都<=0,肯定这就是最大的. 然后这样子就考虑左右两边的状压dp,然后就好了. ...

  3. pycharm光标变成黑框,恢复成竖线

    pycharm光标变成黑框,如下图所示 解决办法: 按外接键盘上的Insert键,即可恢复.

  4. Lua C API 遍历 table

    http://timothyqiu.com/archives/lua-note-table-traversal-using-c-api/ C API 遍历 Table lua_getglobal(L, ...

  5. maven项目无法新增java test目录的问题

    有时候当我们构建好maven项目时,再导入eclipse中会缺少src/main/java  和src/test/java,这是需要我们手动创建: 但是有时候在 项目视图下或者 enterprise ...

  6. Swift5 语言参考(六) 声明

    一个声明引入了一个新的名称或构建到你的程序.例如,您使用声明来引入函数和方法,引入变量和常量,以及定义枚举,结构,类和协议类型.您还可以使用声明来扩展现有命名类型的行为,并将符号导入到其他地方声明的程 ...

  7. spring-boot集成thymeleaf。

    thymeleaf是前台页面展示,原来一直是jsp,jsp中包含很多服务器端的逻辑,逐渐淘汰.同样功能的还有freemarker.孰好孰坏不予评价,只做简单实现. 1.基本思路 (1)pom.xml中 ...

  8. captcha ~ 生成验证码图片

    验证码在我们的世界中可以保护我们的信息安全的一个保障之一 这就是生成验证码的代码     # 导报 from captcha.image import ImageCaptcha #验证码的包 from ...

  9. Ubuntu系统的安装(虚拟机) 并配置C/C++编译器

    一.系统的初始化配置 1.配置静态IP和DNS 配置静态IP 1.sudo vim /etc/network/interfaces,修改文件内容如下: auto eth0  #表示让网卡开机自动挂载e ...

  10. 上台阶问题(递归,DFS)

    题目 一共39层台阶.如果我每一步迈上1个台阶或者两个台阶,先迈左脚,再迈右脚,然后左右交换,最后一步迈右脚,也就是一共要走偶数步,那么,上完39级台阶,有多少种不同的方法? 思路 采用递归的思想,边 ...