Java并行开发笔记5

不可中断的阻塞:

  • Java.io 包中的同步 Socket/IO。 在服务器应用程序中,最常见的阻塞I/O形式就是对套接字进行读取和写入。虽然InputStream和OutputStream中的read和write等方法都不会响应中断,但通过关闭底层的套接字,可以使得由于执行read或write等方法而被阻塞的线程抛出一个SocketException。
  • Java.io包中的同步I/O。 当中断一个正在InterruptibleChannel上等待的线程时,将抛出ClosedByInterruptException并关闭链路(这还会使得其他在这条链路上阻塞的线程同样抛出ClosedByInterruptException)。当关闭一个InterruptibleChannel时,将导致所有在链路操作上阻塞的线程都抛出AsynchronousCloseException。大多数标准的Channel都实现了InterruptibleChannel。
  • Selector的异步I/O。 如果一个线程在调用Selector.select方法(在java.nio.channels中)时阻塞了,那么调用close或wakeup方法会使线程抛出ClosedSelectorException并提前返回。
  • 获取某个锁。 如果一个线程由于等待某个内置锁而阻塞,那么将无法响应中断,因为线程认为它肯定会获得锁,所以将不会理会中断请求。但是,在Lock类中提供了lockInterruptibly方法,该方法允许在等待一个锁的同时仍能响应中断。

  通过改写interrupt方法将非标准的取消操作封装在Thread中

public class ReaderThread extends Thread {
	private static final int BUFSZ = 2048;
	private final Socket socket;
	private final InputStream in;
	
	public ReaderThread(Socket socket) throws IOException{
		this.socket = socket;
		this.in = socket.getInputStream();
	}
	
	@Override
	public void interrupt() {
		try{
			socket.close();
		}catch(IOException ignored)
		{
			
		}finally{
			super.interrupt();
		}
	}

	@Override
	public void run() {
		try {
			byte[] buf = new byte[BUFSZ];
			while(true){
				int count = in.read(buf);
				if(count<0)
					break;
				else if(count>0){
					processBuffer(buf,count);
				}
			}
		} catch (IOException e) {
			/* 允许线程退出 */
		}
	}

	private void processBuffer(byte[] buf, int count) {
		// TODO Auto-generated method stub
		
	}
}

  通过newTaskFor将非标准的取消操作封装在一个任务中

public interface CancellableTask<T> extends Callable<T>{
      void cancel();
      RunnableFuture<T> newTask();
}

@ThreadSafe
public  class CancellingExecutor extends ThreadPoolExecutor{
     ...
     protected<T> RunnableFuture<T> newTaskFor(Callable<T> callable){
          if(callable instanceof CancellableTask)
               return ((CancellableTask<T>) callable).newTask();
          else
               return super.newTaskFor(callable);
     }

}

public abstract class SocketUsingTask<T> implements CancellableTask<T>{

      @GuardedBy("this") private Socket socket;

      protected synchronized void setSocket(Socket s){
         socket = s; 
      }
       
      public synchronized void cancel(){
         try{
            if(socket != null)
                socket.close();
         }catch(IOException ignored){}
      }

      public RunnableFuture<T> newTask(){
          return new FutureTask<T>(this){
               public boolean cancel(boolean mayInterruptIfRunning){
                   try{
                        SocketUsingTask.this.cancel();
                   }finally{
                        return super.cancel(mayInterruptIfRunning);
                   }
               }
          };

      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值