错误用例

下面用例中,一个正在sleep的线程,在调用interrupt后,wait方法检查到isInterrupted()为true,抛出异常, 而catch到异常后没有处理。一个抛出了InterruptedException的线程的在调用interrupt后状态马上就会被置为非中断状态。如果catch语句没有处理异常,则下一 次循环中isInterrupted()为false,线程会继续执行,程序无法正常退出。

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SparkStreamThread implements Runnable { public void stopStream() {
this.log.warn("Stop Stream!!");
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "将要运行...");
while (!Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + "运行中");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "从阻塞中退出...");
System.out.println("this.isInterrupted()=" + Thread.currentThread().isInterrupted());
}
}
System.out.println(Thread.currentThread().getName() + "已经终止!");
} public static void main(String argv[]) throws InterruptedException {
Thread ta = new Thread(new SparkStreamThread());
ta.start();
Thread.sleep(2000);
System.out.println(ta.getName() + "正在被中断...");
ta.interrupt();
System.out.println("ta.isInterrupted()=" + ta.isInterrupted());
}
}

正确用例1,异常捕获后终止线程

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SparkStreamThread implements Runnable { public void stopStream() {
this.log.warn("Stop Stream!!");
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "将要运行...");
while (!Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + "运行中");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "从阻塞中退出...");
Thread.currentThread().interrupt();
System.out.println("this.isInterrupted()=" + Thread.currentThread().isInterrupted());
}
}
System.out.println(Thread.currentThread().getName() + "已经终止!");
} public static void main(String argv[]) throws InterruptedException {
Thread ta = new Thread(new SparkStreamThread());
ta.start();
Thread.sleep(2000);
System.out.println(ta.getName() + "正在被中断...");
ta.interrupt();
System.out.println("ta.isInterrupted()=" + ta.isInterrupted());
}
}
 

正确用例2, 使用变量,double check,二次检查

public class ThreadA extends Thread {
private boolean isInterrupted=false;
int count=0; public void interrupt(){
isInterrupted = true;
super.interrupt();
} public void run(){
System.out.println(getName()+"将要运行...");
while(!isInterrupted){
System.out.println(getName()+"运行中"+count++);
try{
Thread.sleep(400);
}catch(InterruptedException e){
System.out.println(getName()+"从阻塞中退出...");
System.out.println("this.isInterrupted()="+this.isInterrupted()); }
}
System.out.println(getName()+"已经终止!");
}
}

Java——安全地停止线程的更多相关文章

  1. Java如何停止线程?

    在Java编程中,如何停止线程? 以下示例演示了如何通过创建一个用户定义的方法run()方法和Timer类来停止线程. package com.yiibai; import java.util.Tim ...

  2. 深入理解Java中停止线程

    一.停止线程会带来什么? 对于单线程中,停止单线程就是直接使用关键字return或者break,但是在停止多线程时是让线程在完成任务前去开启另外一条线程,必须放弃当前任务,而这个过程是不可预测,所以必 ...

  3. 转: Java安全停止线程方法

    转: http://blog.csdn.net/flyingpig4/article/details/7675557 1.早期Java提供java.lang.Thread类型包含了一些列的方法star ...

  4. Java安全停止线程方法

    1. 早期Java提供java.lang.Thread类型包含了一些列的方法 start(), stop(), stop(Throwable) and suspend(), destroy() and ...

  5. java安全停止线程

    Thread.stop()是一个被废弃的方法,不被推荐使用的原因是stop方法太过于暴力,强行把执行到一半的线程终止,并且会立即释放这个线程所有的锁.会破坏了线程中引用对象的一致性. 使用判断标志位的 ...

  6. Java并发编程的艺术(六)——中断、安全停止线程

    什么是中断 Java的一种机制,用于一个线程去暂停另一个线程的运行.就是一个正在运行的线程被其他线程给打断,停止运行挂起了. 我觉得,在Java中,这种中断机制只是一种方便程序员编写进程间的通信罢了. ...

  7. java线程之停止线程

         在Java中有以下3种方法可以终止一个正在运行的线程:      1.使用退出标志,是线程正常退出,也就是run方法完成后线程终止.      2.使用stop方法强制终止线程,但不推荐使用 ...

  8. JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

    JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...

  9. java中线程的几种状态和停止线程的方法

    1.线程的状态图 需要注意的是:线程调用start方法是使得线程到达就绪状态而不是运行状态 2.停止线程的两种方法 1)自然停止:线程体自然执行完毕 2)外部干涉:通过线程体标识 1.线程类中定义线程 ...

随机推荐

  1. Python学习——Python进程

    python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用的多进程包multiprocessing,只需要定 ...

  2. C中const 定义常量的使用

    先看如下代码 #include <stdio.h> #include <string.h> #define ARRSIZE(a) (sizeof(a)/sizeof(a[0]) ...

  3. 在云端服务器centos7安装jvm并且运行java程序

    (1)在云端服务器 下载jdk http://www.linuxidc.com/Linux/2016-09/134941.htm(大致看这个文章后可以下载一个jdk的压缩包,然后将压缩包解压) 然后, ...

  4. 分布式理论——从ACID到CAP再到BASE

    在传统的数据中,有ACID四大原则,在分布式中也有对应的CAP理论和BASE理论,这些都是分布式理论的基础. 更多内容参考:大数据学习之路 ACID ACID分别是Atomicity 原子性.Cons ...

  5. java监控指定路径下文件及文件夹变化

    之前用jdk7的WatchService API(java.nio.file包)来做目录下的子文件监控,后改为使用commons-io包.主要有下面几点不同:1. WatchService是采用扫描式 ...

  6. SharePoint Online 自定义Modern UI表单

    前言 用过SharePoint Online 版本的朋友们,应该很熟悉SharePoint为我们带来的Modern UI,而这个页面的订制,也跟原来的表单定制方式不同了,而且更加简单了. 而且,试了一 ...

  7. 什么叫做GNU

    GNU就是GNU's Not Unix的缩写, GNU 的创始人Stallman 认为UNIX 虽然不是最 好的操作系统,但是至少不会太差,而他自信有能力把UNIX不足的地方加以改进,使它 成为一个优 ...

  8. .Net Core URL编码和解码

    一.URL说明 .Net Core中http 的常用操作封装在 HttpUtility 中 命名空间 using System.Web; // // 摘要: // Provides methods f ...

  9. WebMagic编译时提示Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom:2.18的解决方法

    问题描述:    从http://git.oschina.net/flashsword20/webmagic 下载最新代码,按照http://webmagic.io/docs/zh/posts/ch3 ...

  10. Scala字符串插值

    Scala提供了三种字符串插值方式:s,f和raw.1. s字符串插值器简单的说就是解析字符串变量. val name = "Tom" println(s"His nam ...