加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 教程 > 正文

Java线程停止方法之Interrupt技巧

发布时间:2021-12-05 17:49:41 所属栏目:教程 来源:互联网
导读:最近在学习Java多线程相关的知识点,其中关于线程停止的方法网上也有不少大牛给出了详细的解答,而我这边就其中Interrupt方法的注意点给自己提个醒。 首先还是大概的罗列下停止线程的方法: 1、使用stop()方法等,不过已经不再被推荐使用,和suspend、resume

最近在学习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方法的例子:
 
class MyThread extends Thread {
    volatile boolean stop = false;
    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( "hread stop..." );
        thread.stop = true;  //如果线程阻塞,将不会检查此变量
        thread.interrupt();
        Thread.sleep( 3000 );
        System.out.println( "end..." );
    }
 
    public void run() {
        while ( !stop ) {
            System.out.println( "Thread running..." );
            try {
                Thread.sleep( 1000 );
            } catch ( InterruptedException e ) {
                System.out.println( "Thread interrupted..." );
            }
        }
        System.out.println( "Thread exiting under request..." );
    }
}
 
说明:对于被上述几种方法阻塞的线程,正确的停止线程方式是设置共享变量,并调用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方法,因为这边容易理解出错!

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读