(43)21.4.3 中断---Java编程思想之并发笔记

本文介绍了Java中如何通过中断机制来取消线程的运行,包括使用Thread类的interrupt()方法和Future的cancel()方法,以及如何处理不同类型的阻塞情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 中断的位置和要处理的资源
       在Runnable.run()方法的中间打断它,当打断被阻塞的任务的时候,可能要清理资源。为了返回良好的状态,必须仔细考虑代码的执行路径,并仔细写catch子句以正确清除所有事物。
2.Thread类中的interrupt()方法,
       可以用来终止任务,这个方法将设置线程的中断状态。如果一个线程已经被阻塞,或者试图执行一个阻塞的操作,那么设置这个线程的中断中断状态将抛出InterruptedException。
       Thread.interrupted()提供了离开run()循环而不抛出异常的第二种方法。
3.调用interrupt()方法
      为了调用interrupt()方法,必须持有Thread对象。新的concurrent类库避免使用Thread对象的操作,尽量用Executor,如果在Executor上调用shutdownNow(),那么将发送一个interrupt()调用给它启动的所有线程。这么做的意义:因为完成工程中某个部分或者整个程序时,通常希望同时关闭某个特定Executor的所有任务。
       有时候希望只中断某个任务,可以使用Executor调用submit()而不是executor()来启动任务,就可以持有该任务的上下文。submit()将返回一个泛型Future<?>其中有一个未修饰的参数,因为永远都不会在其上调用get(),持有这种Future的关键在于你可以在其上调用cancel(),并因此可以使用它来中断某个特定的任务。如果将true传递给cancel(),那么它将会拥有在该线程上调用interrupt()以停止这个线程的权限。因此cancel()是一种中断由Executor启动的单个线程的方式。
4. 例1
package jiangning;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

class SleepBlocked implements Runnable{//sleep blocked

       public void run() {
             try {
                  TimeUnit. SECONDS.sleep(100);
            } catch (InterruptedException e) {
                  System. out.println("InterruptedException" );
            }
      }
}
class IOBlocked implements Runnable{//IO blocked
       private InputStream in ;
       public IOBlocked(InputStream in){
             this.in = in;
      }
       public void run() {
             try {
                  System. out.println("wait for read(): " );
                   in.read();
            } catch (IOException e) {
                   if(Thread.currentThread ().interrupted()){
                        System. out.println("Interrupted from blocked I/O ");
                  } else{
                         throw new RuntimeException(e);
                  }
            }
            System. out.println("Exiting IOBlock.run() " );
      }
}

class SynchronizedBlocked implements Runnable{//synchronized block
       public synchronized void f(){
             while(true ){
                  Thread. yield();
            }
      }
       public SynchronizedBlocked(){
             new Thread(){
                   public void run(){
                        f(); //lock acquired by this Thread
                  }
            }.start();
      }
       public void run() {
            System. out.println("try to call f()" );
            f();
            System. out.println("Exiting SynchronizedBlock.run()" );
      }
      
}
public class Interrupteing {
       private static ExecutorService exec = Executors.newCachedThreadPool();
       static void test(Runnable r ) throws InterruptedException{
            Future<?> f = exec.submit(r);
            TimeUnit. MILLISECONDS.sleep(100);
            System. out.println("Interruping " + r.getClass().getName());
            f.cancel( true);//interrupts if running
            System. out.println("Interrupte sent to " + r.getClass().getName());
            
      }
       public static void main(String[] args) throws Exception{
             test(new SleepBlocked());
             test(new IOBlocked(System. in));
             test(new SynchronizedBlocked());
            TimeUnit. SECONDS.sleep(3);
            System. out.println("Aborting with System.exit(0)" );
            System. exit(0);
      }
}

/**
Interruping jiangning .SleepBlocked
Interrupte sent to jiangning.SleepBlocked
InterruptedException
wait for read():
Interruping jiangning .IOBlocked
Interrupte sent to jiangning.IOBlocked
try to call f()
Interruping jiangning .SynchronizedBlocked
Interrupte sent to jiangning.SynchronizedBlocked
Aborting with System.exit(0)
*/
5.关闭任务在其上发生阻塞的底层资源:
例2.这个例子没有看明白???
package jiangning;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CloseResource {

       public static void main(String[] args) throws Exception {
            ExecutorService exec =  Executors. newCachedThreadPool();
            ServerSocket server = new ServerSocket(8080);
            InputStream sockedInput = new Socket("localhost" ,8080).getInputStream();
            exec.execute( new IOBlocked(sockedInput));
            exec.execute( new IOBlocked(System.in));
            TimeUnit. MILLISECONDS.sleep(100);
            System. out.println("shutdown all Threads" );
            exec.shutdownNow();//关闭所有线程
            TimeUnit. SECONDS.sleep(1);
            System. out.println("closing " + sockedInput.getClass().getName());
            sockedInput.close();
            TimeUnit. SECONDS.sleep(1);
            System. out.println("closing " + System.in.getClass().getName());
            System. in.close();
      }
}


/**
wait for read():
wait for read():
shutdown all Threads
closing java.net.SocketInputStream
Interrupted from blocked I/O
Exiting IOBlock.run()
closing java. io.BufferedInputStream
*/
分析:一旦底层资源被关闭,任务将解除阻塞。interrupt()看起来发生在关闭Socked而不是关闭System.in的时刻。

6.例子3
package jiangning.c21;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

class NIOBlocked implements Runnable{
       private final SocketChannel sc;
       public NIOBlocked(SocketChannel sc){
             this.sc = sc;
      }
       public void run() {
             try {
                  System. out.println("waiting for read() in " + this);
                   sc.read(ByteBuffer. allocate(1));
            } catch (ClosedByInterruptException e) {
                  System. out.println("ClosedByInterruptException" );
            } catch (AsynchronousCloseException e){
                  System. out.println("AsynchronousCloseException" );
            } catch (IOException e){
                   throw new RuntimeException(e);
            }
            System. out.println("exiting NIOBlocked.run()" );
      }
}

public class NIOInterruption {
      
       public static void main(String[] args) throws Exception {
            ExecutorService exec =  Executors. newCachedThreadPool();
            ServerSocket server = new ServerSocket(8080);
            InetSocketAddress isa = new InetSocketAddress("localhost" ,8080);
            SocketChannel sc1 = SocketChannel. open(isa);
            SocketChannel sc2 = SocketChannel. open(isa);
            Future<?> f = exec.submit( new NIOBlocked(sc1));
            exec.execute( new NIOBlocked(sc2));
            exec.shutdown();
            TimeUnit. SECONDS.sleep(1);
            f.cancel( true);
            TimeUnit. SECONDS.sleep(1);
            sc2.close();
      }
}

/**
waiting for read() in jiangning.c21.NIOBlocked@b0bad7
waiting for read() in jiangning.c21.NIOBlocked@ba9340
ClosedByInterruptException
exiting NIOBlocked.run()
AsynchronousCloseException
exiting NIOBlocked.run()
*/

没有太看明白???


7.被互斥所阻塞
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值