Java线程停止方法之Interrupt方法

Wesley13
• 阅读 387

  最近在学习Java多线程相关的知识点,其中关于线程停止的方法网上也有不少大牛给出了详细的解答,而我这边就其中Interrupt方法的注意点给自己提个醒。

  首先还是大概的罗列下停止线程的方法:

  1、使用stop()方法等,不过已经不再被推荐使用,和suspend、resume一样。

  2、使用退出标志终止线程,引入一个共享变量,volatile类型或者使用synchronized来监视共享变量相关操作的方法,然后在run()方法中,通过while循环不停的轮询这个标志。

  3、使用Interrupt方法中断线程。

  注意点:我一开始看到该方法的时候,认为interrupt会使线程停止运行,但事实上并非如此,调用一个线程的Interrupt方法会把线程的状态改为中断态。这其中又可以细分成两个方面:

  1)对于因执行了sleep、wait、join方法而休眠的线程:调用Interrupt方法会使他们不再休眠,同时会抛出 InterruptedException异常。比如一个线程A正在sleep中,这时候另外一个程序里去调用A的interrupt方法,这时就会迫使A停止休眠而抛出InterruptedException异常,从而提前使线程逃离阻塞状态。

  2)对于正在运行的线程,即没有阻塞的线程,调用Interrupt方法就只是把线程A的状态改为interruptted,但是不会影响线程A的继续执行。

以下是对处于阻塞状态线程使用Interrupt方法的例子:

 1 class MyThread extends Thread {  
 2     volatile boolean stop = false;  
 3     public static void main( String args[] ) throws Exception {  
 4         MyThread thread = new MyThread();  
 5         System.out.println( "Starting thread..." );  
 6         thread.start();  
 7         Thread.sleep( 3000 );  
 8         System.out.println( "hread stop..." );  
 9         thread.stop = true;  //如果线程阻塞,将不会检查此变量  
10         thread.interrupt();  
11         Thread.sleep( 3000 );  
12         System.out.println( "end..." );  
13     }  
14   
15     public void run() {  
16         while ( !stop ) {  
17              System.out.println( "Thread running..." );  
18              try {  
19                  Thread.sleep( 1000 );  
20              } catch ( InterruptedException e ) {  
21                  System.out.println( "Thread interrupted..." );  
22              }  
23         }  
24         System.out.println( "Thread exiting under request..." );  
25     }  
26 }

  说明:对于被上述几种方法阻塞的线程,正确的停止线程方式是设置共享变量,并调用interrupt()(注意变量应该先设置)。设置共享变量是为了没有被阻塞的线程也能正常退出。


  以下内容还在继续研究中

  在看一些博主的文章时还看到了一些特殊情况,也在这边做个补充:

  线程在I/O操作进行时被阻塞

  分两种情况:

  1)使用通道(channels)的情况,通道是Java 1.4引入的I/O API,被阻塞的线程将收到一个ClosedByInterruptException异常。这与使用Interrupt方法抛出异常的用法一样,只是异常不同而已。

  2)使用传统的I/O。

  说明:即使Interrupt方法被调用了,Thread.interrupt()也不起作用,因为线程将不会退出被阻塞状态。

  解决办法:调用阻塞该线程的套接字的close()方法。在这种情形下,如果线程被I/O操作阻塞,该线程将接收到一个SocketException异常,这与使用interrupt()方法引起一个InterruptedException异常被抛出非常相似。

  注意:唯一要说明的是,必须存在socket的引用(reference),只有这样close()方法才能被调用。这意味着socket对象必须被共享。

  以下代码供参考:

  

class MyThread extends Thread {  
    volatile boolean stop = false;  
    volatile ServerSocket socket;  

    public static void main( String args[] ) throws Exception {  
        MyThread thread = new MyThread();  
        System.out.println( "Starting thread..." );  
        thread.start();  
        Thread.sleep( 3000 );  
        System.out.println( "Asking thread to stop..." );  
        thread.stop = true;  
        thread.socket.close();  
        Thread.sleep( 3000 );  
        System.out.println( "Stopping application..." );    
     } 
 
    public void run() {  
        try {  
            socket = new ServerSocket(7856);  
        } catch ( IOException e ) {  
            System.out.println( "Could not create the socket..." );  
            return;  
        }  
        while ( !stop ) {  
            System.out.println( "Waiting for connection..." );  
            try {  
                Socket sock = socket.accept();  
            } catch ( IOException e ) {  
                System.out.println( "accept() failed or interrupted..." );  
            }  
        }  
        System.out.println( "Thread exiting under request..." );  
    }  
} 

以上是自己对停止线程方法的一些总结,当然也是借鉴了不少博主的分享。重点放在了Interrupt方法,因为这边容易理解出错!

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
java中线程的几种状态和停止线程的方法
1.线程的状态图!QQ截图20181226161353(https://oscimg.oschina.net/oscnet/18bb17dff6ec4c573367d9e6fe86c407dc1.png"QQ截图20181226161353")(https://www.oschina.net/action/GoToLink?urlhttps%
御弟哥哥 御弟哥哥
3年前
如何正确停止Java线程,终止Java线程的三种方法
如何正确停止Java线程,终止Java线程的三种方法在Java中有以下3种方法可以终止正在运行的线程:1.使用退出标志,使线程正常退出,也就是当run()方法完成后线程终止。2.使用stop()方法强行终止线程,但不推荐,该方法已被弃用,原因见后文。3.使用interrupt方法中断线程。以下内容翻译自J
Wesley13 Wesley13
2年前
java多线程方法笔记【上】
刚开始工作,主要使用c写服务器,不过偶尔也会用到java和python,还是学一学吧。先从java多线程开始。java多线程的基本方法://线程开始运行 public void start( );  //线程运行的方法runpublic void run( );  //线程休眠,单位毫秒 
Wesley13 Wesley13
2年前
java多线程之停止线程
在多线程开发中停止线程是很重要的技术点。停止线程在Java语言中并不像break语句那样干脆,需要一些技巧性的处理。一、 异常法采用异常法来停止一个线程,首先我们需要了解一下两个方法的用法:1、interrupt()方法publicclassMyTh
Wesley13 Wesley13
2年前
java 中断线程的几种方式 interrupt()
中断  中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作。线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序。虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果。你最好还是牢记以下的几点告诫。  首先,忘掉Thread.stop方法。虽然它确实停止了一个正
Wesley13 Wesley13
2年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
2年前
Java多线程学习笔记
Java中创建多线程的三种方法1、继承Thread类创建线程2、实现Runnable接口创建线程3、使用Callable和Future创建线程\
Wesley13 Wesley13
2年前
Java多线程9:中断机制
一、概述  之前讲解Thread类中方法的时候,interrupt()、interrupted()、isInterrupted()三个方法没有讲得很清楚,只是提了一下。现在把这三个方法同一放到这里来讲,因为这三个方法都涉及到多线程的一个知识点中断机制。  Java没有提供一种安全、直接的方法来停止某个线程,而是提供了中断机制。中
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
C# 线程基础
1 线程是进程中的一个执行流 2线程是一个可以单独操作的活动3线程创建和常用方法 a 创建    Thread thnewThread(Method); b常见方法 th.start()//启动线程 th.Abort()//终止线程 Thread.Sleep(n)//休眠线程(停止n毫秒后继续执