本文主要总结在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多线程系列7-停止线程的更多相关文章

  1. java多线程系列六、线程池

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...

  2. (Java多线程系列二)线程间同步

    Java多线程间同步 1.什么是线程安全 通过一个案例了解线程安全 案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 先来看一个线程不安全的例子 class Sell ...

  3. (Java多线程系列三)线程间通讯

    Java多线程间通讯 多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同. 1.使用wait()和notify()方法在线程中通讯 需求:第一个线程写入(input)用户,另一个线程 ...

  4. (Java多线程系列九)线程池

    线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...

  5. Java多线程系列四——控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...

  6. Java多线程系列三——实现线程同步的方法

    两种实现线程同步的方法 方法 特性 synchronized 不需要显式地加解锁,易实现 ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁 ...

  7. java多线程系列8-线程的优先级

    在java中设置线程优先级使用setPriority,在jdk中的源代码如下: public final void setPriority(int newPriority) { ThreadGroup ...

  8. Java多线程系列十——BlockingQueue

    参考资料:http://ifeve.com/java-synchronousqueue/http://www.cnblogs.com/jackyuj/archive/2010/11/24/188655 ...

  9. Java多线程系列--“JUC线程池”01之 线程池架构

    概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容——线程池.内容包括:线程池架构 ...

随机推荐

  1. [转]c#截取指定长度的字符串

    /// <summary> /// 截取指定長度的字符串 /// </summary> /// <param name="s"></par ...

  2. Web开发入门疑问收集(不定期更新)

    bootstrap container和container-fluid的区别 原始链接 container 根据显示设备满足的最小宽度,来决定实际内容宽度,是一个根据设置内容阶梯式响应的布局. 例子: ...

  3. Android 学习笔记之AndBase框架学习(六) PullToRefrech 下拉刷新的实现

    PS:Struggle for a better future 学习内容: 1.PullToRefrech下拉刷新的实现...   不得不说AndBase这个开源框架确实是非常的强大..把大部分的东西 ...

  4. Sprint回顾

    1.回顾组织 主题:“我们下次怎么样才能更加认真对待?” 时间:设定为1至2个小时. 参与者:整个团队. 场所:能够在不受干扰的情况下讨论. 秘书:指定某人当秘书,筹备.记录.整理.  2.回顾流程 ...

  5. 控制器中的Action方法,接收浏览器传过来的参数,总共有几种?

    1.根据配置文件中的URL规则 public ActionResult Delete(int id) //id参数就是根据路由里面的参数id来传过来的,这个action方法中的参数一定要和路由中的id ...

  6. 字符串 - 近似回文词 --- csu 1328

    近似回文词 Problem's Link:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1328 analyse: 直接暴力枚举每一个终点,然后枚举 ...

  7. C# WinForm 技巧八:界面开发之“WeifenLuo.WinFormsUI.Docking+OutLookBar” 使用

    概述 转自 http://www.cnblogs.com/luomingui/archive/2013/09/19/3329763.html 最近几天一直在关注WinFrom方面的文章 有想着提炼一下 ...

  8. HTML5实现音频播放

    Web 上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件(比如 Flash)来播放的.然而,并非所有浏览器都拥有同样的插件. HTML5 规定了一种通过 aud ...

  9. Java NIO中的读和写

    一.概述 读和写是I/O的基本过程.从一个通道中读取只需创建一个缓冲区,然后让通道将数据读到这个缓冲区.写入的过程是创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作. 二.从文件中读取 ...

  10. Azure开发者任务之三:理解Azure应用程序(上)

    作为Windows Azure的托管服务被设计和开发的应用程序由这两部分组成: 1,托管代码 2,XML配置文件 托管代码对应不同的角色 XML文件对应不同的配置设置 我们可以看一下下面这张图,它详细 ...