官术网_书友最值得收藏!

4.3 可中斷套接字

當連接到一個套接字時,當前線程將會被阻塞直到建立連接或產生超時為止。同樣地,當通過套接字讀寫數據時,當前線程也會被阻塞直到操作成功或產生超時為止。

在交互式的應用中,也許會考慮為用戶提供一個選項,用以取消那些看似不會產生結果的連接。但是,當線程因套接字無法響應而發生阻塞時,則無法通過調用interrupt來解除阻塞。

為了中斷套接字操作,可以使用java.nio包提供的一個特性——SocketChannel類。可以使用如下方法打開SocketChannel:

通道(channel)并沒有與之相關聯的流。實際上,它所擁有的read和write方法都是通過使用Buffer對象來實現的(關于NIO緩沖區的相關信息請參見第2章)。ReadableByteChannel接口和WritableByteChannel接口都聲明了這兩個方法。

如果不想處理緩沖區,可以使用Scanner類從SocketChannel中讀取信息,因為Scanner有一個帶ReadableByteChannel參數的構造器:

通過調用靜態方法Channels.newOutputStream,可以將通道轉換成輸出流。

上述操作就是所有要做的事情。當線程正在執行打開、讀取或寫入操作時,如果線程發生中斷,那么這些操作將不會陷入阻塞,而是以拋出異常的方式結束。

程序清單4-5的程序對比了可中斷套接字和阻塞套接字:服務器將連續發送數字,并在每發送十個數字之后停滯一下。點擊兩個按鈕中的任何一個,都會啟動一個線程來連接服務器并打印輸出。第一個線程使用可中斷套接字,而第二個線程使用阻塞套接字。如果在第一批的十個數字的讀取過程中點擊“Cancel”按鈕,這兩個線程都會中斷。

程序清單4-5 interruptible/InterruptibleSocketTest.java

但是,在第一批十個數字之后,就只能中斷第一個線程了,第二個線程將保持阻塞直到服務器最終關閉連接(參見圖4-6)。

圖4-6 中斷一個套接字

java.net.InetSocketAddress 1.4

·InetSocketAddress(String hostname,int port)

用給定的主機和端口參數創建一個地址對象,并在創建過程中解析主機名。如果主機名不能被解析,那么該地址對象的unresolved屬性將被設為true。

·boolean isUnresolved()

如果不能解析該地址對象,則返回true。

java.nio.channels.SocketChannel 1.4

·static SocketChannel open(SocketAddress address)

打開一個套接字通道,并將其連接到遠程地址。

java.nio.channels.Channels 1.4

·static InputStream newInputStream(ReadableByteChannel channel)

創建一個輸入流,用以從指定的通道讀取數據。

·static OutputStream newOutputStream(WritableByteChannel channel)

創建一個輸出流,用以向指定的通道寫入數據。

主站蜘蛛池模板: 莫力| 呼和浩特市| 中卫市| 大渡口区| 襄汾县| 井研县| 丹东市| 信阳市| 子长县| 旬阳县| 林州市| 林周县| 宜宾市| 广饶县| 通海县| 翁牛特旗| 教育| 平安县| 聂荣县| 营山县| 瑞安市| 洪洞县| 大关县| 海安县| 澳门| 内丘县| 城市| 鄂州市| 东阳市| 黎城县| 沙坪坝区| 陵水| 卢湾区| 巴青县| 吴江市| 堆龙德庆县| 日土县| 宜兴市| 阿合奇县| 西峡县| 望江县|