|
3.5.1 非阻塞模式 Socket 通道可以在非阻塞模式下運(yùn)行。這個(gè)陳述雖然簡(jiǎn)單卻有著深遠(yuǎn)的含義。傳統(tǒng)Java socket的阻塞性質(zhì)曾經(jīng)是Java程序可伸縮性的最重要制約之一。非阻塞I/O是許多復(fù)雜的、高性能的程序構(gòu)建的基礎(chǔ)。 要把一個(gè)socket通道置于非阻塞模式,我們要依靠所有socket通道類(lèi)的公有超級(jí)類(lèi):SelectableChannel。下面的方法就是關(guān)于通道的阻塞模式的: - public abstract class SelectableChannel extends AbstractChannel implements Channel {
- // 這里僅列出部分API
- public abstract void configureBlocking (boolean block) throws IOException;
- public abstract boolean isBlocking();
- public abstract Object blockingLock();
- }
有條件的選擇(readiness selection)是一種可以用來(lái)查詢(xún)通道的機(jī)制,該查詢(xún)可以判斷通道是否準(zhǔn)備好執(zhí)行一個(gè)目標(biāo)操作,如讀或?qū)?。非阻?I/O 和可選擇性是緊密相連的,那也正是管理阻塞模式的API代碼要在SelectableChannel超級(jí)類(lèi)中定義的原因。SelectableChannel的剩余API將在第四章中討論。 設(shè)置或重新設(shè)置一個(gè)通道的阻塞模式是很簡(jiǎn)單的,只要調(diào)用configureBlocking()方法即可,傳遞參數(shù)值為true則設(shè)為阻塞模式,參數(shù)值為false值設(shè)為非阻塞模式。真的,就這么簡(jiǎn)單!您可以通過(guò)調(diào)用isBlocking()方法來(lái)判斷某個(gè)socket通道當(dāng)前處于哪種模式: - SocketChannel sc = SocketChannel.open();
- sc.configureBlocking(false); // nonblocking
- //...
- if ( !sc.isBlocking()) {
- doSomething(cs);
- }
服務(wù)器端的使用經(jīng)常會(huì)考慮到非阻塞socket通道,因?yàn)樗鼈兪雇瑫r(shí)管理很多socket通道變得更容易。但是,在客戶端使用一個(gè)或幾個(gè)非阻塞模式的socket通道也是有益處的,例如,借助非阻塞socket通道,GUI程序可以專(zhuān)注于用戶請(qǐng)求并且同時(shí)維護(hù)與一個(gè)或多個(gè)服務(wù)器的會(huì)話。在很多程序上,非阻塞模式都是有用的。 偶爾地,我們也會(huì)需要防止socket通道的阻塞模式被更改。API中有一個(gè)blockingLock()方法,該方法會(huì)返回一個(gè)非透明的對(duì)象引用。返回的對(duì)象是通道實(shí)現(xiàn)修改阻塞模式時(shí)內(nèi)部使用的。只有擁有此對(duì)象的鎖的線程才能更改通道的阻塞模式(對(duì)象的鎖是用同步的 Java 密碼獲取的,它不同于我們?cè)?3.3 節(jié)中介紹的lock()方法)。對(duì)于確保在執(zhí)行代碼的關(guān)鍵部分時(shí)socket通道的阻塞模式不會(huì)改變以及在不影響其他線程的前提下暫時(shí)改變阻塞模式來(lái)說(shuō),這個(gè)方法都是非常方便的。 - Socketsocket= null;
- Object lockObj = serverChannel.blockingLock();
- // have a handle to the lock object, but haven't locked it yet
- // may block here until lock is acquired
- synchronized(lockObj){
- // This thread now owns the lock; mode can't be changed
- boolean prevState = serverChannel.isBlocking();
- serverChannel.configureBlocking (false);
- socket = serverChannel.accept();
- serverChannel.configureBlocking (prevState);
- }
- // lock is now released, mode is allowed to change
- if (socket != null) {
- doSomethingWithTheSocket(socket);
- }
Java nio入門(mén)教程詳解(二十五)
0
0
我們認(rèn)為:用戶的主要目的,是為了獲取有用的信息,而不是來(lái)點(diǎn)擊廣告的。因此本站將竭力做好內(nèi)容,并將廣告和內(nèi)容進(jìn)行分離,確保所有廣告不會(huì)影響到用戶的正常閱讀體驗(yàn)。用戶僅憑個(gè)人意愿和興趣愛(ài)好點(diǎn)擊廣告。
我們堅(jiān)信:只有給用戶帶來(lái)價(jià)值,用戶才會(huì)給我們以回報(bào)。
|