Java终止线程的四种方法
2017-10-05 19:24
232 查看
线程终止常用的四种方式:
终止线程的第一种方式:等待run()或者是call()方法执行完毕
终止线程的第二种方式:设置共享变量,如boolean flag。flag作为线程是否继续执行的标志
终止线程的第三种方式:利用Thread类提供的interrupt()和InterruptedException。
终止线程的第四种方式:利用Thread类提供的interrupt()和isInterrupted()。
线程的核心任务是value自增0.1,但是有两层循环。
终止线程的第一种方式:等待run()或者是call()方法执行完毕,线程自然就结束了(这里run()执行时间太长,不能忍)。
但是很多时候,需要在线程执行过程中终止线程,老版JDK的Thread类提供stop()方法,JDK1.8以后已经被标记为depecated,仍然可以终止线程(已测试),但不建议使用,具体原因网上很多。知道是已废弃的就别用了。。。
终止线程的第二种方式:设置共享变量,如boolean flag。
flag作为线程是否继续执行的标志,属于线程所有。根据需要可以设定为static变量或者实例变量,最好用volatile关键字修饰,这样可以保证flag在线程间的可见性。
如下代码,当flag为true时,线程执行,当需要终止线程时,只需要将该线程对象的flag = false;
终止线程的第三种方式:利用Thread类提供的interrupt()和InterruptedException。
需要注意的是,thread.interrupt()只是会设置thread的interrupt flag,而不会正真的终止线程,因此在thread.interrupt()后,可以利用wait、sleep、join等操作收到interrupt()时会抛出InterruptedException异常的特性来终止线程,try … catch…
示例代码如下:
输出如下:
终止线程的第四种方式:利用Thread类提供的interrupt()和isInterrupted()。
输出如下
以上四种方式中,需要根据实际情况来决定采用何种方式终止线程。
1. 如果线程中存在循环,可用共享变量的方式;
2. 如果需要线程发生终端时返回一些属性,那么建议采用interrupt()+isInterrupted()的方式;
3. 如果线程中存在sleep\wait\join或者其他io操作,则可采用interrupt()+捕获InterruptedException的方式;
补充:关于interrupt
一下是JDK1.8中关于interrupt的实现与说明。
简单的说:
1. 当thread被wait(),sleep(),join()阻塞时,线程状态被清理,同时会收到InterruptedException;
2. 当thread被io,nio阻塞时,也会收到异常;
3. 当1,2都没发生时,thread的 interrupt status被set。
终止线程的第一种方式:等待run()或者是call()方法执行完毕
终止线程的第二种方式:设置共享变量,如boolean flag。flag作为线程是否继续执行的标志
终止线程的第三种方式:利用Thread类提供的interrupt()和InterruptedException。
终止线程的第四种方式:利用Thread类提供的interrupt()和isInterrupted()。
问题引出
考虑下面这段程序:public class MyThread { public static void main(String[] args) throws InterruptedException { Thread thread = new ThreadImpl(); thread.start(); } } class ThreadImpl extends Thread { private static double value = 0; int i = 0, j = 0; @Override public void run() { System.out.println("线程 " + Thread.currentThread().getName() + " 执行之前, value = " + value); while (i++ < Integer.MAX_VALUE) while (j++ < Integer.MAX_VALUE) value += 0.1; System.out.println("线程 " + Thread.currentThread().getName() + " 执行之后, value = " + value); } }
线程的核心任务是value自增0.1,但是有两层循环。
终止线程的第一种方式:等待run()或者是call()方法执行完毕,线程自然就结束了(这里run()执行时间太长,不能忍)。
但是很多时候,需要在线程执行过程中终止线程,老版JDK的Thread类提供stop()方法,JDK1.8以后已经被标记为depecated,仍然可以终止线程(已测试),但不建议使用,具体原因网上很多。知道是已废弃的就别用了。。。
终止线程的第二种方式:设置共享变量,如boolean flag。
flag作为线程是否继续执行的标志,属于线程所有。根据需要可以设定为static变量或者实例变量,最好用volatile关键字修饰,这样可以保证flag在线程间的可见性。
如下代码,当flag为true时,线程执行,当需要终止线程时,只需要将该线程对象的flag = false;
public class MyThread { public static void main(String[] args) throws InterruptedException { ThreadImpl thread = new ThreadImpl(); thread.start(); //do something thread.flag = false; } } class ThreadImpl extends Thread { private static double value = 0; public volatile boolean flag = true;//也可以定义为private,然后利用setter进行赋值 int i = 0, j = 0; @Override public void run() { System.out.println("线程 " + Thread.currentThread().getName() + " 执行之前, value = " + value); while (i++ < Integer.MAX_VALUE && flag) while (j++ < Integer.MAX_VALUE && flag) value += 0.1; System.out.println("线程 " + Thread.currentThread().getName() + " 执行之后, value = " + value); } }
终止线程的第三种方式:利用Thread类提供的interrupt()和InterruptedException。
需要注意的是,thread.interrupt()只是会设置thread的interrupt flag,而不会正真的终止线程,因此在thread.interrupt()后,可以利用wait、sleep、join等操作收到interrupt()时会抛出InterruptedException异常的特性来终止线程,try … catch…
try{ //do something }catch(InterruptedException e){ //do something after interruption }
示例代码如下:
public class MyThread { public static void main(String[] args) { ThreadImpl thread = new ThreadImpl(); thread.start(); thread.interrupt(); if (thread.isInterrupted()) System.out.println("线程被中断"); } } class ThreadImpl extends Thread { public static double value = 0; int i = 0, j = 0; @Override public void run() { try { System.out.println("线程 " + Thread.currentThread().getName() + " 执行之前, value = " + value); while (i++ < Integer.MAX_VALUE) { value += 0.1; Thread.sleep(1000); } System.out.println("线程 " + Thread.currentThread().getName() + " 执行之后, value = " + value); } catch (InterruptedException e) { System.out.println("发生中断时, value = " + value); e.printStackTrace(); } } }
输出如下:
线程被中断 线程 Thread-0 执行之前, value = 0.0 发生中断时, value = 0.1 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep( 4000 Native Method) at threadPool.ThreadImpl.run(MyThread.java:25)
终止线程的第四种方式:利用Thread类提供的interrupt()和isInterrupted()。
public class MyThread { public static void main(String[] args) { ThreadImpl thread = new ThreadImpl(); thread.start(); thread.interrupt(); } } class ThreadImpl extends Thread { public static double value = 0; int i = 0; @Override public void run() { System.out.println("线程 " + Thread.currentThread().getName() + " 执行之前, value = " + value); while (i++ < Integer.MAX_VALUE) { value += 0.1; } System.out.println("线程 " + Thread.currentThread().getName() + " 执行之后, value = " + value); if (this.isInterrupted()) { System.out.println("线程被中断"); return; } } }
输出如下
线程 Thread-0 执行之前, value = 0.0 线程 Thread-0 执行之后, value = 2.1474835660588232E8 线程被中断
以上四种方式中,需要根据实际情况来决定采用何种方式终止线程。
1. 如果线程中存在循环,可用共享变量的方式;
2. 如果需要线程发生终端时返回一些属性,那么建议采用interrupt()+isInterrupted()的方式;
3. 如果线程中存在sleep\wait\join或者其他io操作,则可采用interrupt()+捕获InterruptedException的方式;
补充:关于interrupt
一下是JDK1.8中关于interrupt的实现与说明。
简单的说:
1. 当thread被wait(),sleep(),join()阻塞时,线程状态被清理,同时会收到InterruptedException;
2. 当thread被io,nio阻塞时,也会收到异常;
3. 当1,2都没发生时,thread的 interrupt status被set。
/** * Interrupts this thread. * * <p> Unless the current thread is interrupting itself, which is * always permitted, the {@link #checkAccess() checkAccess} method * of this thread is invoked, which may cause a {@link * SecurityException} to be thrown. * * <p> If this thread is blocked in an invocation of the {@link * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link * Object#wait(long, int) wait(long, int)} methods of the {@link Object} * class, or of the {@link #join()}, {@link #join(long)}, {@link * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, * methods of this class, then its interrupt status will be cleared and it * will receive an {@link InterruptedException}. * * <p> If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel InterruptibleChannel} * then the channel will be closed, the thread's interrupt * status will be set, and the thread will receive a {@link * java.nio.channels.ClosedByInterruptException}. * * <p> If this thread is blocked in a {@link java.nio.channels.Selector} * 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 {@link * java.nio.channels.Selector#wakeup wakeup} method were invoked. * * <p> If none of the previous conditions hold then this thread's interrupt * status will be set. </p> * * <p> Interrupting a thread that is not alive need not have any effect. * * @throws SecurityException * if the current thread cannot modify this thread * * @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(); }
相关文章推荐
- Windows终止线程运行的四种方法
- 【转】Windows终止线程运行的四种方法
- [原]Java多线程编程学习笔记之二:线程挂起、恢复与终止的正确方法(含代码)
- JAVA中终止线程的方法
- Windows终止线程的四种方法
- Java 终止线程的方法
- Java 终止线程方法
- Java中安全终止线程的方法
- java线程interrupt()方法和线程终止方式
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- 【转】Windows终止线程运行的四种方法
- Java 终止线程方法
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- 终止线程的四种方法
- 终止java线程的三种方法
- Java 终止线程方法
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- Java中终止某个线程的方法
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)