Java并发学习之处理不可中断的阻塞
一.不可中断的阻塞
1.我们知道在Java库中,许多可阻塞的方法都是通过提前返回或者抛出InterruptedException来响应中断请求的,从而使开发人员更容易构建出能响应取消请求的任务。
2.然而,并非所有的可阻塞方法或者阻塞机制都能响应中断。 如果一个线程由于执行同步的Socket I/O或者等待获得内置锁而阻塞,那么中断请求只能设置线程的中断状态,除此之外没有其他任何作用。不对中断请求做出任何响应的阻塞我们称之为不可中断的阻塞。
对于那些由于不可中断操作而被阻塞的线程,可以使用类似于中断的手段来停止这些线程,但这要求我们必须知道线程阻塞的原因。
3.java中有哪些阻塞不可被中断:
1)Java.io包中的同步Socket I/O 。 在服务器应用程序中,最常见的阻塞I/O形式就是对套接字进行写入和读取。虽然InputStream和OutputStream中的read和write等方法都不会响应中断,但通过关闭底层的套接字,可以使得由于执行read或者write等方法而被阻塞的线程抛出一个SocketException中断。
2)Java.io包中的同步I/O。 当一个中断正在InterruptibleChannel上等待的线程时,将抛出ClosedByInterruptException并关闭链路(这将还使其他在这条链路上阻塞的线程同样抛出ClosedByInterruptException)。当关闭一个InterruptibleChannel时,将导致所有在链路操作上阻塞的线程都抛出AsynchronousCloseException 。 大多数标准的Channel都是实现了InterruptibleChannel。
3)Selector的异步I/O 。 如果一个线程调用Selector.select方法(在java.nio.channels中)时阻塞了,那么调用close或wakeup方法会使线程抛出ClosedSelectorException并提前返回。
4)获得某个锁。 如果一个线程由于等待某个内置锁而阻塞,那么将无法响应中断,因为线程认为它肯定会获得锁,所以将不会理会中断请求,但是在Lock类中提供lockInterruptibly方法,该方法允许在等待一个锁的同时仍能响应中断。
我们可以像下面的一样处理这种阻塞:
public class ReaderThread extends Thread{
private final Socket socket;//声明一个套接字
private final InputStream in;//声明一个输入楼
public ReaderThread(Socket socket) throws IOException{
this.socket = socket;//获得套接字
this.in = socket.getInputStream();//获得套接字输入流
}
public void interrupt()