<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的家園

    我的家園

    處理不可中斷的阻塞-JCIP7.1讀書筆記

    Posted on 2012-04-15 16:26 zljpp 閱讀(199) 評論(0)  編輯  收藏

    [本文是我對Java Concurrency In Practice 7.1的歸納和總結(jié). ?轉(zhuǎn)載請注明作者和出處, ?如有謬誤, 歡迎在評論中指正. ]

    并不是所有的阻塞都是可中斷的, 比如InputStream.read方法. 在檢測到輸入數(shù)據(jù)可用, 到達流末尾或者拋出異常前, 該方法一直阻塞. 而且阻塞的時候不會檢查中斷標記, 所以中斷線程無法使read從阻塞狀態(tài)返回. 但是關(guān)閉流可以使得read方法拋出異常, 從而從阻塞狀態(tài)返回.?

    public class ReaderThread extends Thread {
    	private static final int BUFSZ = 1024;
    	private final Socket socket;
    	private final InputStream in;
    
    	public ReaderThread(Socket socket) throws IOException {
    		this.socket = socket;
    		this.in = socket.getInputStream();
    	}
    
    	// 覆蓋Thread類的interrupt方法, 加入關(guān)閉socket的代碼
    	// 如果發(fā)生中斷時, 線程阻塞在read方法上, socket的關(guān)閉會導(dǎo)致read方法拋出SocketException, 然后run方法運行完畢
    	public void interrupt() {
    		try {
    			socket.close();
    		} catch (IOException ignored) {
    		} finally {
    			super.interrupt();
    		}
    	}
    
    	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) { /*  Allow thread to exit  */
    		}
    	}
    
    	private void processBuffer(byte[] buf, int count) {
    		//...
    	}
    }

    如果task并非在自己創(chuàng)建的線程里運行, 而是提交給線程池運行的話, 就無法使用上例的方式處理不可中斷阻塞了. 之前有過分析, 對于提交給線程池執(zhí)行的task, 應(yīng)該通過Future.cancel方法提前終止task的運行, 所以可以考慮重寫Future.cancel方法, 在其中加入關(guān)閉socket的操作. Future對象是由submit方法返回的, 其源代碼如下:

    public <T> Future<T> submit(Callable<T> task) {
    	if (task == null) 
    		throw new NullPointerException();
    	RunnableFuture<T> ftask = newTaskFor(task);
    	execute(ftask);
    	return ftask;
    }?

    可知submit方法返回的Future對象是調(diào)用newTaskFor方法獲得的:

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    	return new FutureTask<T>(callable);
    }?

    newTaskFor方法被聲明為protected, 所以我們可以通過繼承覆蓋該方法, 返回自定義的Future對象.

    首先將需要覆蓋的2個方法定義在接口中:

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

    然后讓task類實現(xiàn)CancellableTask接口:

    public abstract class SocketUsingTask<T> implements CancellableTask<T> {
    	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) {
    			// 定義FutureTask的匿名內(nèi)部類, 并覆蓋cancel方法, 向其中加入關(guān)閉socket的操作
    			public boolean cancel(boolean mayInterruptIfRunning) {
    				try {
    					SocketUsingTask.this.cancel();
    				} finally {
    					return super.cancel(mayInterruptIfRunning);
    				}
    			}
    		};
    	}
    }

    接著繼承ThreadPoolExecutor類并覆蓋newTaskFor方法, 讓該方法返回自定義的FutureTask對象:

    public class CancellingExecutor extends ThreadPoolExecutor {
    	// ...
    	protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    		// 如果callable是CancellableTask對象, 那么就返回自定義的FutureTask(通過調(diào)用其newTaskFor方法實現(xiàn))
    		if (callable instanceof CancellableTask)
    			return ((CancellableTask<T>) callable).newTask();
    		else
    			return super.newTaskFor(callable);
    	}
    }

    測試代碼:

    public static void main(String[] args) {
    	CancellingExecutor executor = new CancellingExecutor();
    	SocketUsingTask task = new SocketUsingTask();
    	task.setSocket(new Socket("www.baidu.com", 80));
    	Future<V> future = executor.submit(task);
    	future.cancel(true);
    }





    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲伊人久久精品| 无人在线直播免费观看| 女人18特级一级毛片免费视频| 亚洲免费在线观看| 亚洲国产视频网站| 成人网站免费大全日韩国产| 国产成人免费高清在线观看| 久久久久久亚洲精品影院| 波多野结衣在线免费观看| 亚洲一级二级三级不卡| 日本免费电影一区二区| 亚洲乳大丰满中文字幕| 9i9精品国产免费久久| 亚洲精品一级无码中文字幕| 免费看美女午夜大片| 免费看片在线观看| 久久亚洲国产精品成人AV秋霞| 一二三区免费视频| 亚洲Av无码乱码在线观看性色 | 超清首页国产亚洲丝袜| 亚洲综合av一区二区三区不卡| 日本免费中文视频| 亚洲第一区香蕉_国产a| 成年大片免费高清在线看黄| 在线免费视频一区| 亚洲资源最新版在线观看| 亚洲三级高清免费| 亚洲国产日韩精品| 美女被免费视频网站a国产| 亚洲AV永久无码天堂影院| 国产福利免费观看| 国产精品免费久久久久电影网| 亚洲中文字幕无码中文字在线| 免费A级毛片av无码| 亚洲精品无码你懂的| 亚洲国产婷婷六月丁香| 久久精品女人天堂AV免费观看| 黄页网站在线观看免费| 亚洲高清在线视频| 国产美女精品久久久久久久免费| 全黄大全大色全免费大片|