有时候我们会需要将正在执行的线程进行打断,可能我们会想到使用Thread类的interrupt()方法去打断这个线程,interrupt()能达到我们的要求吗,试一下。
例1:
System.out.println("主线程开始."); TaskD taskD = new TaskD(); try { taskD.start(); Thread.sleep(1000); /* * 虽然taskD进行interrupt,但是并没有真正中断任务执行 * 只是在taskD的run方法sleep时抛出了InterruptedException */ taskD.interrupt(); System.out.println("taskD interrupt..."); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主线程结束.");
线程ThreadD的run方法是使用循环以及sheep来模拟耗时的操作,
可以看到在执行了interrupt操作之后,taskD被打断,sleep抛出了InterruptedException异常。
这种方式达到了我们的目的。
例2:
System.out.println("主线程开始."); TaskF taskF = new TaskF(); try { taskF.start(); Thread.sleep(1000); taskF.interrupt(); /* * 虽然taskF进行interrupt,但是并没有真正中断任务执行 * 业务处理正常执行,没有抛出异常。 */ System.out.println("taskF interrupt..."); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主线程结束.");
线程ThreadF的run方法是使用大数量级的循环来模拟耗时的操作,不使用sheep
可以看到在执行了interrupt操作之后,taskF没有被打断,没有达到我们的目的。
为什么呢,看下api的解释:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。
也就是说,interrupt只能使通过join、wait、sleep等阻塞的线程执行进行中断。
Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
那么正确的方式应该是什么呢?使用interrupt加volatile信号量
例3:
public class TaskG extends Thread { /** * 标记变量可见性,从主存中读取变量最新值 */ private volatile boolean stop = true; public void setStop(boolean stop) { this.stop = stop; } @Override public void run() { System.out.println("TaskG.class start..."); for (int i = 0; i < 500000000; i++) { //模拟耗时操作 if (i % 10000000 == 0 && stop) { System.out.println("TaskF loop " + i / 10000000); } } System.out.println("TaskG.class end..."); } }
System.out.println("主线程开始."); TaskG taskG = new TaskG(); try { taskG.start(); Thread.sleep(1000); /* * 通过信号量标记线程任务终止 */ taskG.setStop(false); /* * 在进行打断操作 * 如果taskG没有被阻塞,那么该语句不起作用 * 如果taskG被阻塞,则会被打断,抛出InterruptedException,可以捕获该异常并进行相应的处理 */ taskG.interrupt(); System.out.println("taskG stop..."); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主线程结束.");
如果线程正在阻塞,那么修改信号量标记时无法起到作用的,所以,所以,所以
正确的终止线程的方式,因该是使用volatile类型的信号量来标记线程的终止状态,并使用interrupt来防止线程正在阻塞。
tips:volatile修饰变量来标记变量的可见性,使当前线程每次都从主存中获取最新值。
相关推荐
在Java早期版本中,提供了`Thread.stop()`方法来直接终止线程,但这种方法存在严重的安全问题。例如,它可能会导致对象处于不稳定的状态,或者在对象的某些关键操作(如资源释放)完成之前就强行终止线程,从而引发...
Java中使用interrupt()终止线程的详细介绍 在Java中,终止线程是一种复杂的操作,需要对线程的状态和中断机制有深入的了解。本文将详细介绍如何使用interrupt()终止线程,并提供了多种终止线程的方式和示例代码。 ...
挂起线程通常通过调用`sleep()`或`wait()`方法实现,恢复线程可能通过`notify()`或`notifyAll()`唤醒,终止线程则可以通过`interrupt()`方法发送中断请求,但线程本身需要检查`isInterrupted()`或`...
interrupt() 方法定义在 Thread 类中,作用是中断本线程。本线程中断自己是被允许的;其它线程调用本线程的 interrupt() 方法时,会通过 checkAccess() 检查权限。这有可能抛出 SecurityException 异常。 如果本...
在Java中,通过实现Runnable接口或者继承Thread类可以创建并运行多线程。本资料"java_Thread.rar"提供了一些Java多线程的实践案例,对于深入理解和应用Java多线程技术具有很高的参考价值。 首先,我们要理解线程的...
public class ThreadInterrupt extends Thread { public void run() { try { Thread.sleep(50000); } catch (InterruptedException e) { System.out.println(e.getMessage()); } } // ... } ``` 在这个...
### Java线程中断机制详解:`interrupt`与`stop`方法 #### 一、引言 在Java多线程编程中,线程控制是至关重要的技术之一。有时我们需要在特定条件下停止某个线程的执行,或者中断正在等待的线程。Java提供了多种...
- **停止**:Java标准库未提供直接终止线程的方法,但可以使用volatile变量、Thread.stop()(不推荐)或共享数据来模拟停止。 3. **为什么不能直接终止线程** - **线程安全**:直接终止可能导致正在执行的关键...
9. **中断线程**:线程可以通过`interrupt()`方法请求中断,但这并不立即终止线程,而是设置一个中断标志。线程内部需要检查这个标志并适当地响应中断请求。 总的来说,理解和掌握Java中的线程应用是成为熟练Java...
JAVA 中终止线程的方法是一种重要的多线程编程技术,在Java中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy()and resume()。通过这些方法,我们可以对线程进行...
本文将详细介绍如何在Java中安全地终止线程,主要讨论三种方法:使用退出标志、停止方法(不推荐)以及中断方法。 1. 使用退出标志终止线程 这是最推荐且安全的方式,通常涉及在一个循环中设置一个布尔类型的退出...
在Java多线程编程中,终止一个线程并非像许多人所理解的那样简单直接。线程的"中断"并不是让线程立即停止执行,而是一个标志,用来指示线程应该中断其当前活动并采取相应措施。Java提供了多种方法来处理线程的中断,...
线程控制是指如何控制线程的执行,如暂停、恢复和终止线程的执行。 线程状态 线程状态是指线程在执行过程中的状态,包括_NEW、RUNNABLE、RUNNING、WAITING、TIMED_WAITING、BLOCKED、TERMINATED等状态。线程状态...
在Java编程语言中,线程是程序执行的基本单元,它允许程序并发地执行多个任务。在多线程环境中,程序的执行效率和响应性通常会得到显著提升。本篇文章将详细探讨如何在Java中启动线程,以及相关的重要概念和技术。 ...
此外,Thread类还提供了interrupt()方法来发送中断请求,但这并不一定会立即停止线程,而是在线程检查中断状态(如在sleep(), wait(), join()等阻塞方法中)时抛出InterruptedException。 除了基本的线程操作,了解...
Java线程Thread是Java多线程编程的核心组件,它允许程序同时执行多个任务,从而提高了程序的并发性和效率。在Java中,线程是程序执行的最小单元,由JVM(Java虚拟机)来调度。了解和掌握Java线程Thread对于开发高效...
在Java编程中,多线程是并发执行任务的重要方式,然而在实际应用中,我们可能会遇到某些线程执行时间过长或死锁的情况,这可能导致系统资源的浪费甚至整体性能下降。因此,对线程进行超时监控是必要的,以确保程序的...
Java提供了多种方法来控制线程状态,如`start()`启动线程,`sleep()`使线程暂停,`join()`等待线程完成,以及`interrupt()`中断线程。 并发控制是线程编程中的重要部分。Java提供了synchronized关键字来实现互斥...