Java停止一个线程的几种方法

来源:互联网 发布:mac网络连接鉴定失败 编辑:程序博客网 时间:2024/04/23 18:36

Java中停止一个线程有三种方法,分别是stop,interrupt和设置标志位,我们依次来看一下这三种方法。

首先不推荐使用stop方法,原因有两点:

1、原则上只要一调用thread.stop()方法,线程就会立即停止,并抛出ThreadDeath error,查看了Thread的源代码后发现,原先Thread.stop0()方法是同步的,而如果我们工作线程的run()方法也是同步,那么这样会导致主线程和工作线程共同争用同一个锁(工作线程对象本身),由于工作线程在启动后就先获得了锁,所以无论如何,当主线程在调用t.stop()时,它必须要等到工作线程的run()方法执行结束后才能进行,结果会使及时性收到影响。

2、thread.stop()是不安全的。它的不安全主要是针对于在停止该线程时会释放该线程所持有的所有的锁。一般任何进行加锁的代码块,都是为了保护数据的一致性,如果在调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。

我们来看interrupt的方法

首先贴一段代码:

class MyThread04 extends Thread {          public MyThread04(String threadName) {         super(threadName);     }     @Override    public void run() {           try{         for (int j = 0; j<100; j++) {                   if(this.isInterrupted()) throw new InterruptedException();                 System.out.println(Thread.currentThread().getName()+":"+j);                 Thread.sleep(10000);         }                  }catch (InterruptedException e) {  //             e.printStackTrace();           }                          }           }

或者是像下面这样写,try.catch块的范围较小,更利于调优

class MyThread04 extends Thread {public MyThread04(String threadName) {super(threadName);}@Overridepublic void run() {// try{for (int j = 0; j < 100; j++) {if (this.isInterrupted())break;System.out.println(Thread.currentThread().getName() + ":" + j);try {Thread.sleep(10000);} catch (InterruptedException e) {// TODO Auto-generated catch blockthis.interrupt();// 由于处于sleep状态的线程被终止后会将标志位复位,所以需要重设一次e.printStackTrace();}}}}


这里之所以抛出异常并捕获是考虑到对一个处于wait或者sleep状态的线程使用interrupt是会抛出异常的,所以需要事先捕获,主进程代码如下:

MyThread04 t=new MyThread04("A");t.start();try {Thread.sleep(5000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}t.interrupt();}

使用interrupt()方法优雅的结束了进程。

我们最后看看设置标志位的方法,代码如下:

class MyThread04 extends Thread {private boolean stop = false;public MyThread04(String threadName) {super(threadName);}@Overridepublic void run() {for (int j = 0; j < 100; j++) {if (this.stop == false) {System.out.println(Thread.currentThread().getName() + ":" + j);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}} else {break;}}}public void setStop() {this.stop = true;}}

只要在主进程中调用setStop()方法就可以了,但此时如果for循环之后仍有代码,那么这些代码还是会被执行,为了避免这一点,我们可以采用抛出异常的方式处理,代码如下:

class MyThread04 extends Thread {private boolean stop = false;public MyThread04(String threadName) {super(threadName);}@Overridepublic void run() {try{for (int j = 0; j < 100; j++) {if (this.stop == false) {System.out.println(Thread.currentThread().getName() + ":" + j);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}} else {throw new InterruptedException();}}}catch (InterruptedException e) {e.printStackTrace();}}public void setStop() {this.stop = true;}}




0 0
原创粉丝点击