线程正常执行完毕,正常结束。

2.监视某些条件,直到某些条件成立,结束线程。

class TestMyThread extends Thread {

private volatile boolean shouldStop;

public TestMyThread(boolean shouldStop) {

this.shouldStop = shouldStop;

}

public void setShouldStop(boolean shouldStop) {

this.shouldStop = shouldStop;

}

@Override

public void run() {

while (!shouldStop) {

System.out.println(getName() + "Thread is running");

}

System.out.println(getName() + "线程退出");

}

}

TestMyThread thread = new TestMyThread(false);

thread.start();

try {

Thread.sleep(1000);

thread.setShouldStop(true);

} catch (InterruptedException e) {

e.printStackTrace();

}

在上面的例子中,如果shouldStop为false,那么线程会一直执行,我们可以在外部调用setShouldStop()方法将shouldStop置为true来结束线程的运行。

上面的方法2存在一个问题:如果线程是阻塞的,则无法结束线程。我们修改一下代码

class TestMyThread extends Thread {

private volatile boolean shouldStop;

public TestMyThread(boolean shouldStop) {

this.shouldStop = shouldStop;

}

public void setShouldStop(boolean shouldStop) {

this.shouldStop = shouldStop;

}

@Override

public void run() {

while (!shouldStop) {

System.out.println(getName() + "Thread is running");

try {

//让线程睡眠

sleep(100000000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(getName() + "线程退出");

}

}

我们让线程睡眠很长一段时间

TestMyThread thread = new TestMyThread(false);

thread.start();

try {

Thread.sleep(1000);

thread.setShouldStop(true);

System.out.println("setShouldStop true");

} catch (InterruptedException e) {

e.printStackTrace();

}

我们发现,即使我们调用setShouldStop()方法将shouldStop置为true,线程依然不会结束。

使用中断来中断一个阻塞的线程

下面是Thread类中断相关的方法。

Thread的interrupt() 方法。

/**

* 中断线程

*

*

如果是其他线程中断当前线程,当前线程的checkAccess()方法会被调用。

* 如果其他线程没有权限修改当前线程,那么会抛出一个SecurityException。

*

*

如果当前线程是由于Object类的下列方法调用

*{@link Object#wait() wait()},

*{@link Object#wait(long) wait(long)},

*{@link Object#wait(long, int) wait(long, int)}

*或者Thread类的下列方法调用

*{@link #join()}, {@link #join(long)}

*{@link #join(long, int)}

*{@link #sleep(long)}

*{@link #sleep(long, int)}

*而阻塞,那么当前线程的中断状态会被清除,并且会收到一个 {@link InterruptedException}.

*

*

如果当前线程是因为在

*{@link java.nio.channels.InterruptibleChannel InterruptibleChannel}

*上的I/O操作而阻塞,那么这个通道会关闭,当前线程的中断状态会被置为true。

*同时当前线程会收到一个 {@link java.nio.channels.ClosedByInterruptException}.

*

* 如果当前线程在 {@link java.nio.channels.Selector}上被阻塞了,那么当前线程的

* 中断状态会被置为true并且当前线程会从selection operation立即返回,

* 同时可能会带有一个非0的值。就像是

* selector的 {@link java.nio.channels.Selector#wakeup wakeup} 方法被调用了。

*

*

如果前面的情况都没有发生,那么当前线程的中断状态会被置为true。

*

*

中断一个死亡的线程不会产生任何影响。

*

* @throws SecurityException 如果当前线程不能被修改

*

* @revised 6.0

* @spec JSR-51

*/

public void interrupt() {

if (this != Thread.currentThread())

checkAccess();

synchronized (blockerLock) {

Interruptible b = blocker;

if (b != null) {

interrupt0(); // Just to set the interrupt flag

b.interrupt(this);

return;

}

}

interrupt0();

}

Thread的isInterrupted() 方法。

/**

* 检测当前线程是否被中断了。这个方法不会影响当前线程的中断状态。

*

线程死亡的时候,线程中断是被忽略的,当前方法会返回false。

*

* @return 如果当前线程被中断了,返回true。否则返回false。

* @see #interrupted()

* @revised 6.0

*/

public boolean isInterrupted() {

return isInterrupted(false);

}

Thread的interrupted() 方法。注意这个方法是静态方法。

/**

* 检测当前线程是否被中断了。该方法会清除当前线程的中断状态。换句话说,

* 如果当前方法被成功调用了两次,

* 如果第一次返回了true,那么第二次会返回false(除非当前线程在当前方法第一次调用之后清除了中断状态和第二次调用之前当前线程被再次中断了)

*

*

线程在死亡的时候,线程中断是被忽略的,当前方法会返回false。

*

* @return 如果当前线程被中断了,返回true。否则返回false。

* @see #isInterrupted()

* @revised 6.0

*/

public static boolean interrupted() {

return currentThread().isInterrupted(true);

}

当使用Thread的interrupt()方法时,线程的中断状态会被设置为true。

下面的例子启动了一个线程,循环执行打印一些信息。使用isInterrupted()方法判断线程是否被中断,如果是就结束线程。

class MyInterruptedThread extends Thread {

@Override

public void run() {

while (!Thread.currentThread().isInterrupted()) {

try {

System.out.println("running");

Thread.sleep(1000);

} catch (InterruptedException e) {

System.out.println("InterruptedException occurred");

//抛出InterruptedException后中断标志被清除,标准做法是再次调用interrupt恢复中断

Thread.currentThread().interrupt();

}

}

System.out.println("stop");

}

public static void main(String[] args) {

MyInterruptedThread thread = new MyInterruptedThread();

thread.start();

try {

Thread.sleep(2000);

thread.interrupt();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

在线程启动后,我们延迟两秒调用interrupt()方法。对线程调用interrupt()方法,不会真正中断正在运行的线程,只是发出一个请求,由线程在合适时候结束自己。

注意:如果线程由于调用Thread类的sleep方法而阻塞,那么当前线程的中断状态会被清除,并且会收到一个 InterruptedException,所以我们在捕捉到这个异常后需要再次调用interrupt方法恢复中断。

使用Future的取消功能来停止一个线程

class MyInterruptedThread extends Thread {

@Override

public void run() {

while (!Thread.currentThread().isInterrupted()) {

try {

System.out.println("running");

Thread.sleep(1000);

} catch (InterruptedException e) {

System.out.println("InterruptedException occurred");

//抛出InterruptedException后中断标志被清除,标准做法是再次调用interrupt恢复中断

Thread.currentThread().interrupt();

}

}

System.out.println("stop");

}

}

MyInterruptedThread thread = new MyInterruptedThread();

ExecutorService executorService = Executors.newSingleThreadExecutor();

Future> future = executorService.submit(thread);

try {

future.get(5, TimeUnit.SECONDS);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

} catch (TimeoutException e) {

e.printStackTrace();

System.out.println("thread over time");

} finally {

//取消

future.cancel(true);

}

调用future.cancel(true);来停止线程。

java 停止一个线程_Java如何停止一个线程相关推荐

  1. java老鸟123怎么样_java入门123——一个老鸟的java学习心得.doc

    java入门123--一个老鸟的java学习心得 java入门123--一个老鸟的java学习心得 篇一:java初学者学习心得 学习Java心得体会 学习了一学期的Java课程,觉得是该总结自己的心 ...

  2. java runnable执行完_java – 如何停止Runnable计划在一定数量的执行后重复执行

    情况 我有一个Runnable.我有一个类,计划这个Runnable执行使用一个ScheduledExecutorService与scheduleWithFixedDelay. 目标 我想改变这个类来 ...

  3. java开发保险案例_Java实现双保险线程的示例代码

    双保险线程,每次启动2个相同的线程,互相检测,避免线程死锁造成影响. 两个线程都运行,但只有一个线程执行业务,但都会检测对方的时间戳 如果时间戳超过休眠时间3倍没有更新的话,则重新启动对方线程. 例子 ...

  4. java condition详解_Java使用Condition控制线程通信的方法实例详解

    Java使用Condition控制线程通信的方法实例详解 发布于 2020-4-20| 复制链接 摘记: 本文实例讲述了Java使用Condition控制线程通信的方法.分享给大家供大家参考,具体如下 ...

  5. java 镶嵌创建线程_Java多线程——之一创建线程的四种方法

    1.实现Runnable接口,重载run(),无返回值 package thread; public class ThreadRunnable implements Runnable { public ...

  6. java 关闭守护线程_Java并发编程之线程生命周期、守护线程、优先级、关闭和join、sleep、yield、interrupt...

    Java并发编程中,其中一个难点是对线程生命周期的理解,和多种线程控制方法.线程沟通方法的灵活运用.这些方法和概念之间彼此联系紧密,共同构成了Java并发编程基石之一. Java线程的生命周期 Jav ...

  7. java代码批量下载_Java代码实战:线程池实现批量下载文件

    今天技术之家陪你一起Java代码实战:线程池实现批量下载文件: 1 创建线程池package com.cheng.webb.thread; import java.util.concurrent.Ar ...

  8. Java报告比较日期_Java程序如果一个日期在另一个日期之后比较日期

    如果某个日期在另一个日期之后,则要比较日期,请使用Calendar.after()方法. Calendar.after()方法返回此Calendar的时间是否晚于指定Object表示的时间.首先,让我 ...

  9. java访问同一个变量_java – 从另一个类访问变量

    很简单的问题,但我不能这样做.我有3个班: DrawCircle类 import java.awt.*; import java.awt.event.*; import javax.swing.*; ...

最新文章

  1. 你想知道的“ROC曲线”
  2. servlet接收multipart/form-data表单数据
  3. vector机器人 WHAT DO VECTOR‘S BACK LIGHTS MEAN? 矢量背光是什么意思?
  4. Java私有变量是否可继承
  5. STM32 电机教程 8 - 步进电机开环电流控制
  6. 玩转mini2440开发板之【使用nfs无法启动的问题(Virtualbox桥接网络)】
  7. C++ auto和decltype关键字
  8. 系统性能评价的关键指标指标
  9. iOS App之间的通信方式
  10. java封装继承多态实验总结_java封装继承多态理解3000字论文
  11. 【PYTHON】【requests】【自定义authen,requests.auth AuthBase】
  12. 第五节 结构化分析模型
  13. Raspberry Pi (树莓派) - 图形化界面启动和命令行界面启动
  14. SOEM 源码解析 ecx_FPWR
  15. Skype for Business Server 2015-07-边缘服务器-1-安装-先决条件
  16. Kali虚拟机和主机的复制粘贴
  17. qpython 3h和oh_**python中的类和他的成员
  18. linux搭建网站教程详解
  19. mysql数据库备份工具
  20. 软件开发版本 Alpha、Beta、RC、GA

热门文章

  1. java卡片布局源码_Java编程使用卡片布局管理器示例【基于swing组件】
  2. python画图中grid等于true_Python3.0科学计算学习之绘图(二)
  3. aaynctask控制多个下载进度_史上最强的进度图绘制十大注意事项!
  4. 图形结构:克隆图,图的遍历的应用,递归和迭代
  5. 分支限界法:单源最短路径--dijkstra算法
  6. Kruskal实现最小生成树
  7. bootstrap学习(四)表格
  8. javascript 查找文本并高亮显示
  9. jquery----js/css 导入
  10. TensorFlow之tf.nn.dropout():防止模型训练过程中的过拟合问题