Java中如何正确的thred 终止线程程

没有更多推荐了,
不良信息举报
举报内容:
Java中如何正确而优雅的终止运行中的线程
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!以下下内容均来自网络,只是整理一下;:)
曾经在,回帖很多,前段时间一直比较忙,没整理。。。;
1) 介绍一下java线程一共有几个状态;
此图来之core java
顺便说下,new一个线程出来后,调用start 方法才是处于runnable ,而不是的run()方法线;
值得注意的是: 线程的可运行状态并不代表线程一定在运行(runnable != running ) 。 大家都知道:所有现代桌面和服务器操作系统都使用了抢占式的线程调度策略 。一旦线程开始执行,并不是总是保持持续运行状态的。当系统分给它的时间片(非常小的运行时间单位)用完以后,不管程序有没有执行完,线程被强制放弃CPU,进入就绪状态,直到下次被调度后开始继续执行。也就是说, Runnable可运行状态的线程处于两种可能的情况下:(1)占用CPU运行中,(2)等待调度的就绪状态。 这里要声明一下:处于等待调度的就绪状态线程和处于阻塞的线程是完全不同的。就绪的线程是因为时间片用完而放弃CPU,其随时都有可能再次获得CPU而运行,这一切取决于分时OS的线程调度策略。()
2)一下内容参考了
文中提到比较和谐的结束一个线程 代码如下
1.继承thread类
public class GracefulTerminationSupportThread extends Thread {
protected volatile boolean running =
public void run() {
while (running) {
// do something as per specific situations
public void terminate() {
interrupt();
public static void main(String[] args) {
GracefulTerminationSupportThread t = new GracefulTerminationSupportThread();
t.start();
// do other things
t.terminate();
2 实现runnable 写法
public class TerminalSignalSupportRunnable implements Runnable {
protected volatile boolean running =
public void run(){
while(running){
public void terminate(Thread threadHandle) {
threadHandle.interrupt();
若把terminate 方法里的 threadHandle.interput()换成如下代码,则不会正常终止,为啥会这样,请见作者博文
Thread.currentThread().interrupt();
3)线程中断 —— interrupt();
对中断是这么解释:
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, themethod of this thread is invoked, which may cause a to be thrown.
If this thread is blocked in an invocation of the, , or methods of the
class, or of the , , , , or, methods of this class, then its interrupt status will be cleared and it will receive an.
If this thread is blocked in an I/O operation upon an then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a.
If this thread is blocked in a
then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
Interrupting a thread that is not alive need not have any effect.
1.当线程不是处于api 提出中的三个if 状态,调用 interrupt() 方法,会改变线程的中断标志。
2.当线程处于三个if状态,调用 interrupt() 方法,只把线程提早的结束阻塞状态(处于阻塞状态的线程,没有获得cpu资源),让线程继续运行,他的中断标志不变,
3. 线程结束运行后的,他的中断标志也是false
4.没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断
接下让我们看下如下程序的运行结果:
public class A extends Thread {public A(){}public void run(){while(!Thread.currentThread().isInterrupted()){System.out.println("A
在中断前:"+Thread.currentThread().isInterrupted());/*try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blockSystem.out.println("--A
在中断异常---:"+isInterrupted());interrupt();System.out.println("######A
异常后继续中断---:"+isInterrupted());e.printStackTrace();}*/}}}
public class c {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubA aa = new A();aa.start();try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("***********************C 中判断前"+aa.isInterrupted());aa.interrupt();// 中断try {Thread.sleep(6000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(" C 中判断 后isInterrupted()*******************;" + aa.isInterrupted());}}
去掉A中的注释,然后在运行
---------------------------------------------------------------------------------------------------------------------------------
以下是一个回帖的内容摘要,这兄弟 ,功底深厚
/* * 如果线程被阻塞,它便不能核查共享变量,也就不能停止。这在许多情况下会发生,例如调用* Object.wait()、ServerSocket.accept()和DatagramSocket.receive()时,他们都可能永* 久的阻塞线程。即使发生超时,在超时期满之前持续等待也是不可行和不适当的,所以,要使* 用某种机制使得线程更早地退出被阻塞的状态。很不幸运,不存在这样一种机制对所有的情况* 都适用,但是,根据情况不同却可以使用特定的技术。使用Thread.interrupt()中断线程正* 如Example1中所描述的,Thread.interrupt()方法不会中断一个正在运行的线程。这一方法* 实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更* 确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,* 它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。因此,* 如果线程被上述几种方法阻塞,正确的停止线程方式是设置共享变量,并调用interrupt()(注* 意变量应该先设置)。如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就* 将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。在任何一种情况中,最* 后线程都将检查共享变量然后再停止。下面示例描述了该技术。* */package Concurrency.Iclass Example3 extends Thread {volatile boolean stop =public static void main(String args[]) throws Exception {Example3 thread = new Example3();System.out.println("Starting thread...");thread.start();Thread.sleep(3000);System.out.println("Asking thread to stop...");/** 如果线程阻塞,将不会检查此变量,调用interrupt之后,线程就可以尽早的终结被阻 * 塞状 态,能够检查这一变量。* */thread.stop =/** 这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退* 出阻 塞的状态* */thread.interrupt();Thread.sleep(3000);System.out.println("Stopping application...");System.exit(0);}public void run() {while (!stop) {System.out.println("Thread running...");try {Thread.sleep(2000);} catch (InterruptedException e) {// 接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态System.out.println("Thread interrupted...");}}System.out.println("Thread exiting under request...");}}/** 把握几个重点:stop变量、run方法中的sleep()、interrupt()、InterruptedException。串接起* 来就是这个意思:当我们在run方法中调用sleep(或其他阻塞线程的方法)时,如果线程阻塞的* 时间过长,比如10s,那在这10s内,线程阻塞,run方法不被执行,但是如果在这10s内,stop被* 设置成true,表明要终止这个线程,但是,现在线程是阻塞的,它的run方法不能执行,自然也就* 不能检查stop,所 以线程不能终止,这个时候,我们就可以用interrupt()方法了:我们在* thread.stop =语句后调用thread.interrupt()方法, 该方法将在线程阻塞时抛出一个中断* 信号,该信号将被catch语句捕获到,一旦捕获到这个信号,线程就提前终结自己的阻塞状态,这* 样,它就能够 再次运行run 方法了,然后检查到stop = true,while循环就不会再被执行,在执* 行了while后面的清理工作之后,run方法执行完 毕,线程终止。* */
在上一篇Ibm社区关于
Dealing with InterruptedException;
浏览: 13331 次
来自: 杭州
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'java中,如何安全的结束一个正在运行的线程?
我的图书馆
java中,如何安全的结束一个正在运行的线程?
  问题  Java中提供了很多调度线程的方法,上一节介绍了其中一种控制线程的方法:如何等待一个线程结束。那么如果不希望等待线程结束,而是根据问题的需要随时都要中断线程使其结束,这种对线程的控制方法该如何实现呢?  解决思路  首先必须先明确“中断”这个概念的实际含义,这里的中断是指一个线程在其任务完成之前被强行停止,提前消亡的过程。查阅JDK的帮助文档,可以找到这样一个和中断有关的方法:interrupt()。  它的语法格式如下所示:  public void interrupt()  该方法的功能是中断一个线程的执行。但是,在实际使用当中发现,这个方法不一定能够真地中断一个正在运行的线程。下面通过一个例子来看一看使用interrput()方法中断一个线程时所出现的结果。程序代码如下所示:  // 例4.4.1 InterruptThreadDemo.java  class MyThread extends Thread  {  public void run()  {  while(true) // 无限循环,并使线程每隔1秒输出一次字符串  {&  System.out.println(getName()+' is running');&  try{&  sleep(1000);  }catch(InterruptedException e){  System.out.println(e.getMessage());  }  }  }  }  class InterruptThreadDemo  {  public static void main(String[] args) throws InterruptedException  {  MyThread m=new MyThread(); // 创建线程对象m  System.out.println('Starting thread...');  m.start(); // 启动线程m  Thread.sleep(2000); //主线程休眠2秒,使线程m一直得到执行  System.out.println('Interrupt thread...');  m.interrupt(); // 调用interrupt()方法中断线程m  Thread.sleep(2000); // 主线程休眠2秒,观察中断后的结果  System.out.println('Stopping application...'); // 主线程结束  }  }  这个程序的本意是希望,当程序执行到m.interrupt()方法后,线程m将被中断并进入消亡状态。然而运行这个程序,屏幕里显示了出人意料的结果,如图4.4.1所示。  通过对结果的分析,可以发现,用户线程在调用了interrupt()方法之后并没有被中断,而是继续执行,直到人为地按下Ctrl+C或者Pause键为止。这个例子说明一个事实,直接使用interrput()方法并不能中断一个正在运行的线程。那么用什么样的方法才能中断一个正在运行的线程呢?    图 4.4.1 对线程调用了interrupt()  通过查阅JDK,有些读者可能会看到Thread类中所提供的stop()方法。但是在这里需要强调的是,虽然该方法确实能够停止一个正在运行的线程,但是该方法是不安全的,因为有时使用它会导致严重的系统错误。例如一个线程正在等待关键的数据结构,并只完成了部分地改变,如果在这一时刻停止该线程,那么数据结构将会停留在错误的状态上。正因为如此,在Java后期的版本中,它将不复存在。因此,使用stop()方法来中断一个线程是不合适的。  这时我们想到了使用共享变量的方式,通过一个共享信号变量来通知线程是否需要中断,如果需要中断,则停止正在执行的任务,否则让任务继续执行。这种方式是如何实现的呢?  具体步骤  在这种方式中,之所以引入共享变量,是因为该变量可以被多个执行相同任务的线程用来作为是否中断的信号,通知中断线程的执行。下面通过在程序中引入共享变量来改进前面例4.4.1,改进后的代码如下所示:  // 例4.4.2 InterruptThreadDemo2.java  class MyThread extends Thread  {  boolean stop = // 引入一个布尔型的共享变量stop  public void run()  {  while(!stop) // 通过判断stop变量的值来确定是否继续执行线程体  {  System.out.println(getName()+' is running');  try  {  sleep(1000);&  }catch(InterruptedException e){  System.out.println(e.getMessage());  }  }  System.out.println('Thread is exiting...');  }  }  class InterruptThreadDemo2  {  public static void main(String[] args) throws InterruptedException  {  MyThread m=new MyThread();  System.out.println('Starting thread...');  m.start();  Thread.sleep(3000);&  System.out.println('Interrupt thread...');  m.stop= // 修改共享变量  Thread.sleep(3000); // 主线程休眠以观察线程中断后的情况  System.out.println('Stopping application...');  }  }  在使用共享变量来中断一个线程的过程中,线程体通过循环来周期性的检查这一变量的状态。如果变量的状态改变,说明程序发出了立即中断该线程的请求,此时,循环体条件不再满足,结束循环,进而结束线程的任务。程序执行的结果如图4.4.2所示:    图4.4.2 引入共享变量来中断线程  其中,主程序中的第二个Thread.sleep(3000);语句就是用来使程序不提早结束,以便观察线程m的中断情况。结果是一旦将共享变量stop设置为true,则中断立即发生。  为了更加安全起见,通常需要将共享变量定义为volatile类型或者将对该共享变量的一切访问封装到同步的代码或者同步方法中去。后者所提到的技术将在第4.5节中介绍。  在多线程的程序中,当出现有两个或多个线程共享同一实例变量的情况时,每一个线程可以保持这个实例变量自己的私有副本,变量的实际备份在不同时间被更新。而问题就是变量的主备份总是需要反映它的当前状态,此时反而使效率降低。为保证效率,只需要简单地指定变量为volatile类型即可,它可以告诉编译器必须总是使用volatile变量的主备份(或者至少总是保持任何私有的备份和最新的备份一样,反之亦然)。同样,对主变量的访问必须同任何私有备份一样,精确地顺序执行。  如果需要一次中断所有由同一线程类创建的线程,该怎样实现呢?有些读者可能马上就想到了对每一个线程对象通过设置共享变量的方式来中断线程。这种方法当然可以,那么有没有更好的方法呢?  此时只需将共享变量设置为static类型的即可。然后在主程序中当需要中断所有同一个线程类创建的线程对象时,使用MyThread.stop=语句就可实现对所有同一个线程类创建的线程对象的中断操作,而且效率明显提高。读者不妨试一试。  专家说明  通过本节介绍了如何中断一个正在执行的线程,既不是用stop()方法,也不是用interrupt()方法,而是通过引入了共享变量的形式有效地解决了线程中断的问题。其实这种方法有很多好处,它避免了一些无法想象的意外情况的发生,特别是将共享变量所访问的一切代码都封装到同步方法中以后,安全性将更高。在本节中,还可以尝试创建多个线程来检验这种中断方式的好处。此外,还介绍了volatile类型说明符的作用,这更加有助于提高中断线程的效率,值得提倡。  专家指点  本小节不仅要掌握如何使用共享变量的方法来中断一个线程,还要明白为什么使用其他方法来中断线程就不安全。其实,在多线程的调度当中还会出现一个问题,那就是死锁。死锁的出现将导致线程间均无法向前推进,从而陷入尴尬的局面。因此,为减少出现死锁的发生,Java 1.2以后的版本中已经不再使用Thread类的stop(),suspend(),resume()以及destroy()方法。特别是不安全的stop()方法,原因就是它会解除由线程获取的所有锁定,而且一旦对象处于一种不连贯的状态,那么其他线程就能在那种状态下检查和修改它们,结果导致很难再检查出问题的真正所在。因此最好的方法就是,用一个标志来告诉线程什么时候应该退出自己的run()方法,并中断自己的执行。通过后面小节的学习将会更好的理解这个问题。  相关问题  如果一个线程由于等待某些事件的发生而被阻塞,又该如何实现该线程的中断呢?比如当一个线程由于需要等候键盘输入而被阻塞,处于不可运行状态时,即使主程序中将该线程的共享变量设置为true,但该线程此时根本无法检查循环标志,当然也就无法立即中断。  其实,这种情况经常会发生,比如调用Thread.join()方法,或者Thread.sleep()方法,在网络中调用ServerSocket.accept()方法,或者调用了DatagramSocket.receive()方法时,都有可能导致线程阻塞。即便这样,仍然不要使用stop()方法,而是使用Thread提供的interrupt()方法,因为该方法虽然不会中断一个正在运行的线程,但是它可以使一个被阻塞的线程抛出一个中断异常,从而使线程提前结束阻塞状态,退出堵塞代码。  下面看一个例子来说明这个问题:  // 例4.4.3 InterruptThreadDemo3.java  class MyThread extends Thread  {  volatile boolean stop =  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= // 在异常处理代码中修改共享变量的状态  }  }  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  m1.interrupt(); // 阻塞时退出阻塞状态  Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断情况  System.out.println('Stopping application...');  }  }  程序中如果线程m1发生了阻塞,那么虽然执行了m1.stop=语句,但是stop的值并未改变。为了能够中断该线程,必须在异常处理语句中对共享变量的值进行重新设置,从而实现了在任何情况下都能够中断线程的目的。  一定要记住,m1.interrupt();语句只有当线程发生阻塞时才有效。它的作用就是抛出一个InterruptedException类的异常对象,使try…catch语句捕获异常,并对其进行处理。请读者仔细研究这个程序,以便能够看出其中的巧妙之处。
TA的最新馆藏[转]&
喜欢该文的人也喜欢停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。
在java中有以下3种方法可以终止正在运行的线程:
使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。
使用interrupt方法中断线程。
1. 停止不了的线程
interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i&500000; i++){
System.out.println(&i=&+(i+1));
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
输出结果:
2. 判断线程是否停止状态
Thread.java类中提供了两种方法:
this.interrupted(): 测试当前线程是否已经中断;
this.isInterrupted(): 测试线程是否已经中断;
那么这两个方法有什么图区别呢?
我们先来看看this.interrupted()方法的解释:测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程。
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i&500000; i++){
System.out.println(&i=&+(i+1));
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
System.out.println(&stop 1??& + thread.interrupted());
System.out.println(&stop 2??& + thread.interrupted());
} catch (InterruptedException e) {
e.printStackTrace();
运行结果:
stop 1??false
stop 2??false
类Run.java中虽然是在thread对象上调用以下代码:thread.interrupt(), 后面又使用
System.out.println(&stop 1??& + thread.interrupted());
System.out.println(&stop 2??& + thread.interrupted());
来判断thread对象所代表的线程是否停止,但从控制台打印的结果来看,线程并未停止,这也证明了interrupted()方法的解释,测试当前线程是否已经中断。这个当前线程是main,它从未中断过,所以打印的结果是两个false.
如何使main线程产生中断效果呢?
public class Run2 {
public static void main(String args[]){
Thread.currentThread().interrupt();
System.out.println(&stop 1??& + Thread.interrupted());
System.out.println(&stop 2??& + Thread.interrupted());
System.out.println(&End&);
运行效果为:
stop 1??true
stop 2??false
方法interrupted()的确判断出当前线程是否是停止状态。但为什么第2个布尔值是false呢? 官方帮助文档中对interrupted方法的解释:
测试当前线程是否已经中断。线程的中断状态由该方法清除。 换句话说,如果连续两次调用该方法,则第二次调用返回false。
下面来看一下inInterrupted()方法。
public class Run3 {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
thread.interrupt();
System.out.println(&stop 1??& + thread.isInterrupted());
System.out.println(&stop 2??& + thread.isInterrupted());
运行结果:
stop 1??true
stop 2??true
isInterrupted()并为清除状态,所以打印了两个true。
3. 能停止的线程--异常法
有了前面学习过的知识点,就可以在线程中用for语句来判断一下线程是否是停止状态,如果是停止状态,则后面的代码不再运行即可:
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i&500000; i++){
if(this.interrupted()) {
System.out.println(&线程已经终止, for循环不再执行&);
System.out.println(&i=&+(i+1));
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
运行结果:
线程已经终止, for循环不再执行
上面的示例虽然停止了线程,但如果for语句下面还有语句,还是会继续运行的。看下面的例子:
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i&500000; i++){
if(this.interrupted()) {
System.out.println(&线程已经终止, for循环不再执行&);
System.out.println(&i=&+(i+1));
System.out.println(&这是for循环外面的语句,也会被执行&);
使用Run.java执行的结果是:
线程已经终止, for循环不再执行
这是for循环外面的语句,也会被执行
如何解决语句继续运行的问题呢? 看一下更新后的代码:
public class MyThread extends Thread {
public void run(){
super.run();
for(int i=0; i&500000; i++){
if(this.interrupted()) {
System.out.println(&线程已经终止, for循环不再执行&);
throw new InterruptedException();
System.out.println(&i=&+(i+1));
System.out.println(&这是for循环外面的语句,也会被执行&);
} catch (InterruptedException e) {
System.out.println(&进入MyThread.java类中的catch了。。。&);
e.printStackTrace();
使用Run.java运行的结果如下:
线程已经终止, for循环不再执行
进入MyThread.java类中的catch了。。。
java.lang.InterruptedException
at thread.MyThread.run(MyThread.java:13)
4. 在沉睡中停止
如果线程在sleep()状态下停止线程,会是什么效果呢?
public class MyThread extends Thread {
public void run(){
super.run();
System.out.println(&线程开始。。。&);
Thread.sleep(200000);
System.out.println(&线程结束。&);
} catch (InterruptedException e) {
System.out.println(&在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:& + this.isInterrupted());
e.printStackTrace();
使用Run.java运行的结果是:
线程开始。。。
在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thread.MyThread.run(MyThread.java:12)
从打印的结果来看, 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。
前一个实验是先sleep然后再用interrupt()停止,与之相反的操作在学习过程中也要注意:
public class MyThread extends Thread {
public void run(){
super.run();
System.out.println(&线程开始。。。&);
for(int i=0; i&10000; i++){
System.out.println(&i=& + i);
Thread.sleep(200000);
System.out.println(&线程结束。&);
} catch (InterruptedException e) {
System.out.println(&先停止,再遇到sleep,进入catch异常&);
e.printStackTrace();
public class Run {
public static void main(String args[]){
Thread thread = new MyThread();
thread.start();
thread.interrupt();
运行结果:
先停止,再遇到sleep,进入catch异常
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thread.MyThread.run(MyThread.java:15)
5. 能停止的线程---暴力停止
使用stop()方法停止线程则是非常暴力的。
public class MyThread extends Thread {
private int i = 0;
public void run(){
super.run();
while (true){
System.out.println(&i=& + i);
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
public class Run {
public static void main(String args[]) throws InterruptedException {
Thread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.stop();
运行结果:
Process finished with exit code 0
6.方法stop()与java.lang.ThreadDeath异常
调用stop()方法时会抛出java.lang.ThreadDeath异常,但是通常情况下,此异常不需要显示地捕捉。
public class MyThread extends Thread {
private int i = 0;
public void run(){
super.run();
this.stop();
} catch (ThreadDeath e) {
System.out.println(&进入异常catch&);
e.printStackTrace();
public class Run {
public static void main(String args[]) throws InterruptedException {
Thread thread = new MyThread();
thread.start();
stop()方法以及作废,因为如果强制让线程停止有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。
7. 释放锁的不良后果
使用stop()释放锁将会给数据造成不一致性的结果。如果出现这样的情况,程序处理的数据就有可能遭到破坏,最终导致程序执行的流程错误,一定要特别注意:
public class SynchronizedObject {
private String name = &a&;
private String password = &aa&;
public synchronized void printString(String name, String password){
this.name =
Thread.sleep(100000);
this.password =
} catch (InterruptedException e) {
e.printStackTrace();
public String getName() {
public void setName(String name) {
this.name =
public String getPassword() {
public void setPassword(String password) {
this.password =
public class MyThread extends Thread {
private SynchronizedObject synchronizedO
public MyThread(SynchronizedObject synchronizedObject){
this.synchronizedObject = synchronizedO
public void run(){
synchronizedObject.printString(&b&, &bb&);
public class Run {
public static void main(String args[]) throws InterruptedException {
SynchronizedObject synchronizedObject = new SynchronizedObject();
Thread thread = new MyThread(synchronizedObject);
thread.start();
Thread.sleep(500);
thread.stop();
System.out.println(synchronizedObject.getName() + &
& + synchronizedObject.getPassword());
输出结果:
由于stop()方法以及在JDK中被标明为“过期/作废”的方法,显然它在功能上具有缺陷,所以不建议在程序张使用stop()方法。
8. 使用return停止线程
将方法interrupt()与return结合使用也能实现停止线程的效果:
public class MyThread extends Thread {
public void run(){
while (true){
if(this.isInterrupted()){
System.out.println(&线程被停止了!&);
System.out.println(&Time: & + System.currentTimeMillis());
public class Run {
public static void main(String args[]) throws InterruptedException {
Thread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
输出结果:
线程被停止了!
不过还是建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止事件得以传播。
阅读(...) 评论()
PS:如果你觉得文章对你有所帮助,别忘了推荐或者分享,因为有你的支持,才是我续写下篇的动力和源泉!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。有事请联系邮箱.

我要回帖

更多关于 java结束线程 的文章

 

随机推荐