锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
浠final int x=911] , [static final int x=912]涓轟緥,jdk1.6.0_16(涓轟綍濡傛鐗堟湰璇︾粏,鏄洜涓轟笅闈㈣繕鏈変釜jdk鐨刡ug).
鏍蜂緥綾?
class Test {
private final int x=911;//modifiers:final->18,non-final->2
static final private int y=912;//modifiers:final->26,non-final->10
public int getX(){
return x;
}
public static int getY(){
return y;
}
}
Java涓殑final field鎰忔寚甯擱噺,璧嬪間竴嬈?涓嶅彲鏀瑰彉.緙栬瘧鍣ㄤ細瀵筬inal field榪涜濡備笅鐨勪紭鍖?
e.g:
Test t=new Test();
鍑℃槸鍦ㄧ▼搴忎腑瀵箃.x鐨勫紩鐢?緙栬瘧鍣ㄩ兘灝嗕互瀛楅潰鍊?11鏇挎崲,getX()涓殑return x涔熶細琚浛鎹㈡垚return 911;
鎵浠ュ氨綆楀湪榪愯鏃朵綘鏀瑰彉浜唜鐨勫間篃鏃犳祹浜庝簨,緙栬瘧鍣ㄥ瀹冧滑榪涜鐨勬槸闈欐佺紪璇?
浣嗘槸Test.class.getDeclaredField("x").getInt(t)闄ゅ;
閭d箞濡備綍鍦ㄨ繍琛屾椂鏀瑰彉final field x鐨勫煎憿?
private final int x=911;Field.modifiers涓?8,鑰宲rivate int x=911;Field.modifiers涓?.
鎵浠ュ鏋滄垜浠慨鏀笷ield[Test.class.getDeclaredField("x")].modifiers鐢?8[final]鍙樹負2[non-final],閭d箞浣犲氨鍙互淇敼x鐨勫間簡.
Test tObj=new Test();
Field f_x=Test.class.getDeclaredField("x");
//淇敼modifiers 18->2
Field f_f_x=f_x.getClass().getDeclaredField("modifiers");
f_f_x.setAccessible(true);
f_f_x.setInt(f_x, 2/*non-final*/);
f_x.setAccessible(true);
f_x.setInt(tObj, 110);//鏀瑰彉x鐨勫間負110.
System.out.println("闈欐佺紪璇戠殑x鍊?"+tObj.getX()+".------.榪愯鏃舵敼鍙樹簡鐨勫?10:"+f_x.getInt(tObj));
f_x.setInt(tObj, 111);//浣犲彲浠ョ戶緇敼鍙榵鐨勫間負.
System.out.println(f_x.getInt(tObj));
浣嗘槸鎯蟲仮澶嶅師鏉ョ殑modifiers,f_f_x.setInt(f_x, 18/*final*/);榪欐槸鏃犳晥鐨?鍥犱負Field鍙細鍒濆鍖栧畠鐨凢ieldAccessor寮曠敤涓嬈?
鍦ㄤ笂闈㈢殑榪囩▼涓?鎴戣繕鍙戠幇浜嗕釜jdk bug,浣犲鏋滃皢涓婇潰鐨勭孩鑹蹭唬鐮佹敼涓哄涓嬬殑浠g爜:
f_f_x.setInt(f_x, 10/*榪欎釜鏁板兼槸static non-final modifiers,鑰寈鏄?strong>non-static鐨?榪欐牱灝變細浣縡_x寰楀埌涓涓猻tatic FieldAccessor*/);閭d箞浼氬紩鍙慉 fatal error has been detected by the Java Runtime Environment.騫朵駭鐢熺浉搴旂殑err log鏂囦歡.鏄劇劧JVM娌℃湁瀵硅繖縐嶆儏鍐靛姞浠ュ鐞?鎴戝凡鎻愪氦to sun bug report site.
sun 浜?010-3-26閫氱煡鎴?浠栦滑宸叉壙璁よbug,bug id : 6938467.鍙戝竷鍒板緗戝彲鑳芥湁涓鍒頒袱澶╃殑寤惰繜.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6938467
涓嬮潰鍒嗗埆鏄疢INA,xSocket,Grizzly鐨勬簮鐮佸垎鏋?
Apache MINA (mina-2.0.0-M6婧愮爜涓轟緥):
鎴戜滑浣跨敤mina nio tcp鏈甯哥敤鐨勬牱渚嬪涓?
NioSocketAcceptor acceptor = new NioSocketAcceptor(/*NioProcessorPool's size*/);
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
//chain.addLast("codec", new ProtocolCodecFilter(
//new TextLineCodecFactory()));
......
// Bind
acceptor.setHandler(/*our IoHandler*/);
acceptor.bind(new InetSocketAddress(port));
------------------------------------------------------------------------------------
棣栧厛浠嶯ioSocketAcceptor(extends AbstractPollingIoAcceptor)寮濮?
bind(SocketAddress)--->bindInternal--->startupAcceptor:鍚姩AbstractPollingIoAcceptor.Acceptor.run浣跨敤executor[Executor]鐨勭嚎紼?娉ㄥ唽[interestOps:SelectionKey.OP_ACCEPT],鐒跺悗wakeup selector.
涓鏃︽湁榪炴帴榪涙潵灝辨瀯寤篘ioSocketSession--瀵瑰簲--channal,鐒跺悗session.getProcessor().add(session)灝嗗綋鍓嶇殑channal鍔犲叆鍒癗ioProcessor鐨剆elector涓幓[interestOps:SelectionKey.OP_READ],榪欐牱姣忎釜榪炴帴涓湁璇鋒眰榪囨潵灝辯敱鐩稿簲鐨凬ioProcessor鏉ュ鐞?
榪欓噷鏈夊嚑鐐硅璇存槑鐨勬槸:
1.涓涓狽ioSocketAcceptor瀵瑰簲浜嗗涓狽ioProcessor,姣斿NioSocketAcceptor灝變嬌鐢ㄤ簡SimpleIoProcessorPool DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1.褰撶劧榪欎釜size鍦╪ew NioSocketAcceptor鐨勬椂鍊欏彲浠ヨ瀹?
2.涓涓狽ioSocketAcceptor瀵瑰簲涓涓猨ava nio selector[OP_ACCEPT],涓涓狽ioProcessor涔熷搴斾竴涓猨ava nio selector[OP_READ].
3.涓涓狽ioSocketAcceptor瀵瑰簲涓涓唴閮ㄧ殑AbstractPollingIoAcceptor.Acceptor---thread.
4.涓涓狽ioProcessor涔熷搴斾竴涓唴閮ㄧ殑AbstractPollingIoProcessor.Processor---thread.
5.鍦╪ew NioSocketAcceptor鐨勬椂鍊欏鏋滀綘涓嶆彁渚?strong>Executor(綰跨▼姹?鐨勮瘽,閭d箞榛樿浣跨敤Executors.newCachedThreadPool().
榪欎釜Executor灝嗚NioSocketAcceptor鍜孨ioProcessor鍏敤,涔熷氨鏄涓婇潰鐨凙cceptor---thread(涓鏉?鍜孭rocessor---thread(澶氭潯)閮芥槸婧愪簬榪欎釜Executor.
褰撲竴涓繛鎺ava nio channal--NioSession琚姞鍒?strong>ProcessorPool[i]--NioProcessor涓幓鍚庡氨杞叆浜咥bstractPollingIoProcessor.Processor.run,
AbstractPollingIoProcessor.Processor.run鏂規硶鏄繍琛屽湪涓婇潰鐨?strong>Executor涓殑涓鏉$嚎紼嬩腑鐨?褰撳墠鐨凬ioProcessor灝嗗鐞嗘敞鍐屽湪瀹冪殑selector涓婄殑鎵鏈夎繛鎺ョ殑璇鋒眰[interestOps:SelectionKey.OP_READ].
AbstractPollingIoProcessor.Processor.run鐨勪富瑕佹墽琛屾祦紼?
for (;;) {
......
int selected = selector(final SELECT_TIMEOUT = 1000L);
.......
if (selected > 0) {
process();
}
......
}
process()-->for all session-channal:OP_READ -->read(session):榪欎釜read鏂規硶鏄疉bstractPollingIoProcessor.private void read(T session)鏂規硶.
read(session)鐨勪富瑕佹墽琛屾祦紼嬫槸read channal-data to buf,if readBytes>0 then IoFilterChain.fireMessageReceived(buf)/*鎴戜滑鐨処oHandler.messageReceived灝嗗湪鍏朵腑琚皟鐢?/strong>*/;
鍒版mina Nio 澶勭悊璇鋒眰鐨勬祦紼嬪凡緇忔槑浜?
mina澶勭悊璇鋒眰鐨勭嚎紼嬫ā鍨嬩篃鍑烘潵浜?鎬ц兘闂涔熸潵浜?/strong>,閭e氨鏄湪AbstractPollingIoProcessor.Processor.run-->process-->read(per session)涓?鍦╬rocess鐨勬椂鍊檓ina鏄?strong>for all selected-channals 閫愭read data鍐峟ireMessageReceived鍒版垜浠殑IoHandler.messageReceived涓?/strong>,鑰屼笉鏄茍鍙戝鐞?/strong>,榪欐牱涓鏉ュ緢鏄庢樉鍚庢潵鐨勮姹傚皢琚?strong>寤惰繜澶勭悊.
鎴戜滑鍋囪:濡傛灉NioProcessorPool's size=2 鐜板湪鏈?00涓鎴風鍚屾椂榪炴帴榪囨潵,鍋囪姣忎釜NioProcessor閮芥敞鍐屼簡100涓繛鎺?瀵逛簬姣忎釜NioProcessor灝?strong>渚濇欏哄簭澶勭悊榪?00涓姹?閭d箞榪欏叾涓殑絎?00涓姹傝寰楀埌澶勭悊,閭e畠鍙湁絳夊埌鍓嶉潰鐨?9涓澶勭悊瀹屼簡.
鏈変漢鎻愬嚭浜嗘敼榪涙柟妗?閭e氨鏄湪鎴戜滑鑷繁鐨処oHandler.messageReceived涓埄鐢ㄧ嚎紼嬫睜鍐嶈繘琛屽垎鍙慸ispatching,榪欎釜褰撶劧鏄釜濂戒富鎰?
浣嗘槸璇鋒眰榪樻槸琚歡榪熷鐞嗕簡,鍥犱負榪樻湁read data鎵娑堣楃殑鏃墮棿,榪欐牱絎?00涓姹傚畠鐨勬暟鎹琚,灝辮絳夊墠闈㈢殑99涓兘琚瀹屾墠琛?鍗充究鏄鍔燩rocessorPool鐨勫昂瀵鎬篃涓嶈兘瑙e喅榪欎釜闂.
姝ゅmina鐨?strong>闄烽槺(榪欎釜璇嶈緝鏃墮)涔熷嚭鏉ヤ簡,灝辨槸鍦?strong>read(session)涓?鍦ㄨ榪欎釜闄烽槺涔嬪墠鍏堣鏄庝竴涓?鎴戜滑鐨刢lient绔悜server绔彂閫佷竴涓秷鎭綋鐨勬椂鍊欎笉涓瀹氭槸瀹屾暣鐨勫彧鍙戦佷竴嬈?鍙兘鍒嗗嬈″彂閫?鐗瑰埆鏄湪client绔繖鎴栬鍙戦佺殑娑堟伅浣撶殑闀垮害杈冮暱鐨勬椂鍊?/strong>.鑰宮ina鍦ㄨ繖縐嶆儏鍐典笅灝變細call鎴戜滑鐨処oHandler.messageReceived澶氭,緇撴灉灝辨槸娑堟伅浣撹鍒嗗壊浜嗚嫢騫蹭喚,絳変簬鎴戜滑鍦↖oHandler.messageReceived涓瘡嬈″鐞嗙殑鏁版嵁閮芥槸涓嶅畬鏁寸殑,榪欎細瀵艱嚧鏁版嵁涓㈠け,鏃犳晥.
涓嬮潰鏄痳ead(session)鐨勬簮鐮?
private void read(T session) {
IoSessionConfig config = session.getConfig();
IoBuffer buf = IoBuffer.allocate(config.getReadBufferSize());
final boolean hasFragmentation =
session.getTransportMetadata().hasFragmentation();
try {
int readBytes = 0;
int ret;
try {
if (hasFragmentation/*hasFragmentation涓瀹氫負ture,涔熻mina鐨勫紑鍙戜漢鍛樹篃鎰忚瘑鍒頒簡浼犺緭鏁版嵁鐨勭鐗囬棶棰?浣嗘槸闈犱笅闈㈢殑澶勭悊鏄繙榪滀笉澶熺殑,鍥犱負client涓鏃﹂棿闅斿彂閫?ret灝卞彲鑳戒負0,閫鍑簑hile,涓嶅畬鏁寸殑readBytes灝嗚fire*/) {
while ((ret = read(session, buf)) > 0) {
readBytes += ret;
if (!buf.hasRemaining()) {
break;
}
}
} else {
ret = read(session, buf);
if (ret > 0) {
readBytes = ret;
}
}
} finally {
buf.flip();
}
if (readBytes > 0) {
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireMessageReceived(buf);
buf = null;
if (hasFragmentation) {
if (readBytes << 1 < config.getReadBufferSize()) {
session.decreaseReadBufferSize();
} else if (readBytes == config.getReadBufferSize()) {
session.increaseReadBufferSize();
}
}
}
if (ret < 0) {
scheduleRemove(session);
}
} catch (Throwable e) {
if (e instanceof IOException) {
scheduleRemove(session);
}
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireExceptionCaught(e);
}
}
榪欎釜闄烽槺澶у鍙互嫻嬭瘯涓涓?鐪嬩細涓嶄細涓涓畬鏁寸殑娑堟伅琚嬈″彂閫?浣犵殑IoHandler.messageReceived鏈夋病鏈夎澶氭璋冪敤.
瑕佷繚鎸佹垜浠簲鐢ㄧ▼搴忔秷鎭綋鐨勫畬鏁存т篃寰堢畝鍗曞彧闇鍒涘緩涓涓柇鐐筨reakpoint,鐒跺悗set it to the current IoSession,涓鏃︽秷鎭綋鏁版嵁瀹屾暣灝眃ispatching it and remove it from the current session.
--------------------------------------------------------------------------------------------------
涓嬮潰浠Socket v2_8_8婧愮爜涓轟緥:
tcp usage e.g:
IServer srv = new Server(8090, new EchoHandler());
srv.start() or run();
-----------------------------------------------------------------------
class EchoHandler implements IDataHandler {
public boolean onData(INonBlockingConnection nbc)
throws IOException,
BufferUnderflowException,
MaxReadSizeExceededException {
String data = nbc.readStringByDelimiter("\r\n");
nbc.write(data + "\r\n");
return true;
}
}
------------------------------------------------------------------------
璇存槑1.Server:Acceptor:IDataHandler ------1:1:1
Server.run-->IoAcceptor.accept()鍦╬ort涓婇樆濉?涓鏃︽湁channel灝變粠IoSocketDispatcherPool涓幏鍙栦竴涓狪oSocketDispatcher,鍚屾椂鏋勫緩涓涓狪oSocketHandler鍜孨onBlockingConnection,璋冪敤Server.LifeCycleHandler.onConnectionAccepted(ioHandler) initialize the IoSocketHandler.娉ㄦ剰:IoSocketDispatcherPool.size榛樿涓?,涔熷氨鏄鍙湁2鏉o select鐨勭嚎紼嬪拰鐩稿簲鐨?涓狪oSocketDispatcher.榪欎釜鍜孧INA鐨凬ioProcessor鏁版槸涓鏍風殑.
璇存槑2.IoSocketDispatcher[java nio Selector]:IoSocketHandler:NonBlockingConnection------1:1:1
鍦↖oSocketDispatcher[瀵瑰簲涓涓猄elector].run涓?-->IoSocketDispatcher.handleReadWriteKeys:
for all selectedKeys
{
IoSocketHandler.onReadableEvent/onWriteableEvent.
}
IoSocketHandler.onReadableEvent鐨勫鐞嗚繃紼嬪涓?
1.readSocket();
2.NonBlockingConnection.IoHandlerCallback.onData
NonBlockingConnection.onData--->appendDataToReadBuffer: readQueue append data
3.NonBlockingConnection.IoHandlerCallback.onPostData
NonBlockingConnection.onPostData--->HandlerAdapter.onData[our dataHandler] performOnData in WorkerPool[threadpool].
鍥犱負鏄妸channel涓殑鏁版嵁璇誨埌readQueue涓?搴旂敤紼嬪簭鐨刣ataHandler.onData浼氳澶氭璋冪敤鐩村埌readQueue涓殑鏁版嵁璇誨畬涓烘.鎵浠ヤ緷鐒跺瓨鍦ㄧ被浼糾ina鐨勯櫡闃?瑙e喅鐨勬柟娉曚緷鐒剁被浼?鍥犱負榪欓噷鏈塏onBlockingConnection.
----------------------------------------------------------------------------------------------
鍐嶄笅闈互grizzly-nio-framework v1.9.18婧愮爜涓轟緥:
tcp usage e.g:
Controller sel = new Controller();
sel.setProtocolChainInstanceHandler(new DefaultProtocolChainInstanceHandler(){
public ProtocolChain poll() {
ProtocolChain protocolChain = protocolChains.poll();
if (protocolChain == null){
protocolChain = new DefaultProtocolChain();
//protocolChain.addFilter(our app's filter/*搴旂敤紼嬪簭鐨勫鐞嗕粠filter寮濮?綾諱技mina.ioHandler,xSocket.dataHandler*/);
//protocolChain.addFilter(new ReadFilter());
}
return protocolChain;
}
});
//濡傛灉浣犱笉澧炲姞鑷繁鐨凷electorHandler,Controller灝遍粯璁や嬌鐢═CPSelectorHandler port:18888
sel.addSelectorHandler(our app's selectorHandler on special port);
sel.start();
------------------------------------------------------------------------------------------------------------
璇存槑1.Controller:ProtocolChain:Filter------1:1:n,Controller:SelectorHandler------1:n,
SelectorHandler[瀵瑰簲涓涓猄elector]:SelectorHandlerRunner------1:1,
Controller. start()--->for per SelectorHandler start SelectorHandlerRunner to run.
SelectorHandlerRunner.run()--->selectorHandler.select() then handleSelectedKeys:
for all selectedKeys
{
NIOContext.execute:dispatching to threadpool for ProtocolChain.execute--->our filter.execute.
}
浣犱細鍙戠幇榪欓噷娌℃湁read data from channel鐨勫姩浣?鍥犱負榪欏皢鐢變綘鐨刦ilter鏉ュ畬鎴?鎵浠ヨ嚜鐒舵病鏈塵ina,xsocket瀹冧滑鐨勯櫡闃遍棶棰?鍒嗗彂鎻愬墠浜?浣嗘槸浣犺娉ㄦ剰SelectorHandler:Selector:SelectorHandlerRunner:Thread[SelectorHandlerRunner.run]閮芥槸1:1:1:1,涔熷氨鏄鍙湁涓鏉$嚎紼嬪湪doSelect then handleSelectedKeys.
鐩告瘮涔嬩笅铏界劧grizzly鍦?strong>騫跺彂鎬ц兘涓婃洿浼?浣嗘槸鍦?strong>鏄撶敤鎬?/strong>鏂歸潰鍗翠笉濡俶ina,xsocket,姣斿綾諱技mina,xsocket涓〃紺哄綋鍓嶈繛鎺ユ垨浼氳瘽鐨処oSession,INonBlockingConnection瀵硅薄鍦╣rizzly涓敱NIOContext鏉ヨ礋璐?浣嗘槸NIOContext騫舵病鏈夋彁渚泂ession/connection lifecycle event,浠ュ強甯歌鐨剅ead/write鎿嶄綔,榪欎簺閮介渶瑕佷綘鑷繁鍘繪墿灞昐electorHandler鍜孭rotocolFilter,浠庡彟涓涓柟闈篃鍙互璇存槑grizzly鐨勫彲鎵╁睍鎬?鐏墊椿鎬ф洿鑳滀竴絳?
org.apache.tomcat.util.net.NioEndpoint.start()-->
TaskQueue taskqueue = new TaskQueue();/***queue.capacity==Integer.MAX_VALUE***/
TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-");
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60,TimeUnit.SECONDS,taskqueue, tf);
taskqueue.setParent( (ThreadPoolExecutor) executor, this);
2.*****濡傛灉鎶奓inkedBlockingQueue.capacity璁劇疆涓轟竴涓傚綋鐨勫艱繙灝忎簬Integer.MAX_VALUE,閭d箞鍙湁put鍒皅ueue鐨勪換鍔℃暟鍒拌揪LinkedBlockingQueue鐨刢apacity鍚?鎵嶄細緇х畫澧炲姞姹犱腑鐨勭嚎紼?浣垮緱poolSize瓚呭嚭corePoolSize浣嗕笉瓚呰繃maximumPoolSize,榪欎釜鏃跺欐潵澧炲姞綰跨▼鏁版槸涓嶆槸鏈夌偣鏅氫簡鍛??????*****.
榪欐牱涓鏉eject(command)涔熷彲鑳介殢涔嬭屾潵浜?LinkedBlockingQueue.capacity璁劇疆涓轟綍鍊煎張鏄釜澶寸柤鐨勯棶棰?
鎵浠hreadPoolExecutor+LinkedBlockingQueue琛ㄨ揪鐨勬剰鎬濇槸棣栧厛浼氬鍔犵嚎紼嬫暟鍒癱orePoolSize,浣嗗彧鏈塹ueue鐨勪換鍔″閲忓埌杈炬渶澶apacity鍚?鎵嶄細緇х畫鍦╟orePoolSize鐨勫熀鏁頒笂澧炲姞綰跨▼鏉ュ鐞嗕換鍔?鐩村埌maximumPoolSize.
浣嗕負浠涔堟垜浠笉鑳借繖鏍峰憿:灝哃inkedBlockingQueue.capacity璁劇疆涓篒nteger.MAX_VALUE,璁﹖ask灝藉彲鑳界殑寰楀埌澶勭悊,鍚屾椂鍦ㄥ繖鐨勬儏鍐典笅,澧炲姞姹犱腑鐨勭嚎紼嬪厖鍒癿aximumPoolSize鏉ュ敖蹇殑澶勭悊榪欎簺浠誨姟.鍗充究鏄妸LinkedBlockingQueue.capacity璁劇疆涓轟竴涓傚綋鐨勫?lt;<<榪滃皬浜嶪nteger.MAX_VALUE,涔熶笉涓瀹氶潪寰楀湪浠誨姟鏁板埌杈綥inkedBlockingQueue鐨刢apacity涔嬪悗鎵嶅幓澧炲姞綰跨▼浣縫oolSize瓚呭嚭corePoolSize瓚嬪悜maximumPoolSize.
鎵浠ava util concurrent涓殑ThreadPoolExecutor+LinkedBlockingQueue緇勫悎鐨勭己鐐逛篃灝卞嚭鏉ヤ簡:濡傛灉鎴戜滑鎯寵綰跨▼姹犲敖鍙兘澶氱殑澶勭悊澶ч噺鐨勪換鍔$殑璇?鎴戜滑浼氭妸LinkedBlockingQueue.capacity璁劇疆涓篒nteger.MAX_VALUE,浣嗘槸濡傛灉榪欐牱鐨勮瘽姹犱腑鐨勭嚎紼嬫暟閲忓氨涓嶈兘鍏呭埌鏈澶aximumPoolSize,涔熷氨涓嶈兘鍏呭垎鍙戞尌綰跨▼姹犵殑鏈澶у鐞嗚兘鍔?濡傛灉鎴戜滑鎶奓inkedBlockingQueue.capacity璁劇疆涓轟竴涓緝灝忕殑鍊?閭d箞綰跨▼姹犱腑鐨勭嚎紼嬫暟閲忎細鍏呭埌鏈澶aximumPoolSize,浣嗘槸濡傛灉姹犱腑鐨勭嚎紼嬮兘蹇欑殑璇?綰跨▼姹犲張浼歳eject璇鋒眰鐨勪換鍔?鍥犱負闃熷垪宸叉弧.
濡傛灉鎴戜滑鎶奓inkedBlockingQueue.capacity璁劇疆涓轟竴涓緝澶х殑鍊間絾涓嶆槸Integer.MAX_VALUE,閭d箞絳夊埌綰跨▼姹犵殑綰跨▼鏁伴噺鍑嗗寮濮嬭秴鍑篶orePoolSize鏃?涔熷氨鏄換鍔¢槦鍒楁弧浜?榪欎釜鏃跺欐墠鍘誨鍔犵嚎紼嬬殑璇?璇鋒眰浠誨姟鐨勬墽琛屼細鏈変竴瀹氱殑寤舵椂,涔熷氨鏄病鏈夊緱鍒板強鏃剁殑澶勭悊.
鍏跺疄涔熷氨鏄ThreadPoolExecutor緙轟箯鐏墊晱鐨勭嚎紼嬭皟搴︽満鍒?娌℃湁鏍規嵁褰撳墠浠誨姟鐨勬墽琛屾儏鍐?鏄繖,榪樻槸闂?浠ュ強闃熷垪涓殑寰呭鐞嗕換鍔$殑鏁伴噺綰ц繘琛屽姩鎬佺殑璋冮厤綰跨▼鏁?浣垮緱瀹冪殑澶勭悊鏁堢巼鍙楀埌褰卞搷.
閭d箞浠涔堟槸蹇欑殑鎯呭喌鐨勫垽鏂憿?
busy[1]:濡傛灉poolSize==corePoolSize,騫朵笖鐜板湪蹇欑潃鎵ц浠誨姟鐨勭嚎紼嬫暟(currentBusyWorkers)絳変簬poolSize.[鑰屼笉綆$幇鍦╬ut鍒皅ueue鐨勪換鍔℃暟鏄惁鍒拌揪queue.capacity]
busy[2].1:濡傛灉poolSize==corePoolSize,騫朵笖put鍒皅ueue鐨勪換鍔℃暟宸插埌杈緌ueue.capacity.[queue.capacity鏄拡瀵規湁浠誨姟闃熷垪鏋侀檺闄愬埗鐨勬儏鍐礭
busy[2].2:綰跨▼姹犵殑鍩烘湰鐩爣鏄敖鍙兘鐨勫揩閫熷鐞嗗ぇ閲忕殑璇鋒眰浠誨姟,閭d箞灝變笉涓瀹氶潪寰楀湪put鍒皅ueue鐨勪換鍔℃暟鍒拌揪queue鐨刢apacity涔嬪悗鎵嶅垽鏂負蹇欑殑鎯呭喌,鍙queue涓幇鏈夌殑浠誨姟鏁?task_counter)涓巔oolSize鎴栬卪aximumPoolSize瀛樺湪涓瀹氱殑姣斾緥鏃跺氨鍙互鍒ゆ柇涓哄繖鎯?姣斿task_counter>=poolSize鎴栬卪aximumPoolSize鐨?NumberOfProcessor+1)鍊?榪欐牱queue.capacity榪欎釜闄愬埗鍙互鍙栨秷浜?
鍦ㄤ笂榪癰usy[1],busy[2]榪?縐嶆儏鍐典笅閮藉簲澧炲姞綰跨▼鏁?鐩磋嚦maximumPoolSize,浣胯姹傜殑浠誨姟寰楀埌鏈蹇殑澶勭悊.
鍓嶉潰璁茬殑鏄繖鐨勬椂鍊橳hreadPoolExecutor+LinkedBlockingQueue鍦ㄥ鐞嗕笂鐨勭憰鐤?閭d箞絀洪棽鐨勬椂鍊欏張瑕佸浣曞憿?
濡傛灉corePoolSize<poolSize<maximumPoolSize,閭d箞綰跨▼絳夊緟keepAliveTime涔嬪悗搴旇闄嶄負corePoolSize,鍢垮樋,榪欎釜灝辯湡鐨勬垚浜哹ug浜嗗摝,涓涓緢闅懼彂鐜扮殑bug,poolSize鏄闄嶄笅鏉ヤ簡,鍙槸寰堝彲鑳介檷榪囦簡澶?lt;corePoolSize,鐢氳嚦闄嶄負0涔熸湁鍙兘.
ThreadPoolExecutor.Worker.run()-->ThreadPoolExecutor.getTask():
Runnable getTask() {
for (;;) {
try {
int state = runState;
if (state > SHUTDOWN)
return null;
Runnable r;
if (state == SHUTDOWN) // Help drain queue
r = workQueue.poll();
else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
/*queue is empty,榪欓噷timeout涔嬪悗,return null,涔嬪悗call workerCanExit() return true.*/
r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
else
r = workQueue.take();
if (r != null)
return r;
if (workerCanExit()) {
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers();
return null;
}
// Else retry
} catch (InterruptedException ie) {
// On interruption, re-check runState
}
}
}//end getTask.
private boolean workerCanExit() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
boolean canExit;
try {
canExit = runState >= STOP ||
workQueue.isEmpty() ||
(allowCoreThreadTimeOut &&
poolSize > Math.max(1, corePoolSize));
} finally {
mainLock.unlock();
}
return canExit;
}//end workerCanExit.
鍦╳orkerCanExit() return true涔嬪悗,poolSize浠嶇劧澶т簬corePoolSize,pooSize鐨勫兼病鏈夊彉鍖?
ThreadPoolExecutor.Worker.run()灝嗙粨鏉?->ThreadPoolExecutor.Worker.workerDone-->榪欎釜鏃跺欐墠灝唒oolSize--,鍙儨鏅氫簡,鍦ㄥ綰跨▼鐨勭幆澧冧笅,poolSize鐨勫煎皢鍙樹負灝忎簬corePoolSize,鑰屼笉鏄瓑浜巆orePoolSize!!!!!!
渚嬪:濡傛灉poolSize(6)澶т簬corePoolSize(5),閭d箞鍚屾椂timeout鐨勫氨涓嶄竴瀹氭槸涓鏉$嚎紼?鑰屾槸澶氭潯,瀹冧滑閮芥湁鍙兘閫鍑簉un,浣垮緱poolSize--鍑忚繃浜哻orePoolSize.
鎻愪竴涓媕ava.util.concurrent.ThreadPoolExecutor鐨刟llowCoreThreadTimeOut鏂規硶, @since 1.6 public void allowCoreThreadTimeOut(boolean value);
瀹冭〃杈劇殑鎰忔濇槸鍦ㄧ┖闂茬殑鏃跺欒綰跨▼絳夊緟keepAliveTime,timeout鍚庝嬌寰梡oolSize鑳藉闄嶄負0.[鍏跺疄鎴戞槸甯屾湜瀹冮檷涓簃inimumPoolSize,鐗瑰埆鏄湪鏈嶅姟鍣ㄧ殑鐜涓?鎴戜滑闇瑕佺嚎紼嬫睜淇濇寔涓瀹氭暟閲忕殑綰跨▼鏉ュ強鏃跺鐞?闆墮浂紕庣鐨?鏂柇緇畫鐨?涓鑲′竴娉㈢殑,涓嶆槸寰堟湁鍘嬪姏鐨?璇鋒眰],褰撶劧浣犲彲浠ユ妸corePoolSize褰撲綔minimumPoolSize,鑰屼笉璋冪敤璇ユ柟娉?
閽堝涓婅堪java util concurrent綰跨▼姹犵殑鐟曠柕,鎴戝java util concurrent綰跨▼姹犳ā鍨嬭繘琛屼簡淇,鐗瑰埆鏄湪"蹇?(busy[1],busy[2])鐨勬儏鍐典笅鐨勪換鍔″鐞嗚繘琛屼簡浼樺寲,浣垮緱綰跨▼姹犲敖鍙兘蹇殑澶勭悊灝藉彲鑳藉鐨勪換鍔?
涓嬮潰鎻愪緵浜嗛珮鏁堢殑綰跨▼姹犵殑婧愮爜璐拱:
java鐗坱hreadpool:
http://item.taobao.com/auction/item_detail-0db2-9078a9045826f273dcea80aa490f1a8b.jhtml
c [not c++]鐗坱hreadpool in windows NT:
http://item.taobao.com/auction/item_detail-0db2-28e37cb6776a1bc526ef5a27aa411e71.jhtml
浠巘omcat6寮濮?澧炲姞浜唎rg.apache.catalina.CometProcessor鎺ュ彛鏉ュ疄鐜板comet鎶鏈殑鏀寔.
淇敼conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"-鏀逛負->"org.apache.coyote.http11.Http11NioProtocol"
java:璇峰弬鐪媡omcat.apache.org涓婄殑CometServlet鐨勪緥瀛?
import javax.servlet.http.HttpServlet;
import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;
CometServlet extends HttpServlet implements CometProcessor
javascript:
function installComet(){
var xmlReq = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
xmlReq.onreadystatechange = handler;
xmlReq.open("GET", "/yourapp/comet",true);
xmlReq.send();
}
function handler(){
try{
if(xmlReq.readyState){
if(xmlReq.readyState>=3){
alert(xmlReq.responseText);
}
}
}catch(e){
alert(xmlReq.readyState+":e->:"+e.message);
}
}
鍦↖E嫻忚鍣ㄥ悇涓増鏈腑handler鍙細琚洖璋冧竴嬈¤屼笉綆℃湇鍔$閽堝姝ゆ榪炴帴鍙戝灝戞娑堟伅,姝ゆ椂鐨剅eadyState涓?
瀵箁esponseText鐨勬搷浣滀細寮曞彂javascript error:瀹屾垚璇ユ搷浣滄墍闇鐨勬暟鎹繕涓嶅彲浣跨敤銆?/p>
鍦‵irefox涓環andler浼氳澶氭璋冪敤,浣唕esponseText浼氱紦瀛樺墠涓嬈$殑娑堟伅鑰屼笉浼氭竻闄?responseText鐨勬暟鎹細闅忕潃鏈嶅姟绔秷鎭殑鍒拌揪鑰岀瘡縐?
鍒扮洰鍓嶄負姝?嫻忚鍣ㄥ彧鑳介氳繃鎻掍歡鐨勬柟寮忔潵瀹炵幇瀵筩omet鎶鏈湪瀹㈡埛绔殑鏀寔,鎵浠ユ祦琛岀殑flash player,ActionScript灝辨垚涓轟簡棣栭?
ActionScript閫氳繃socket鏉ュ緩绔嬮暱榪炴帴.
鎵浠ラ偅浜汚JAX妗嗘灦閮戒笉鑳界湡姝g殑鏀寔comet,鑰屽彧鑳介氳繃poll,setTimeout/setInterval,
鑰宒wr鐨凴everseAjax姝f槸浣跨敤浜唖etTimeout鏉oll杞鏈嶅姟绔殑,璇峰弬鐪媎wr鐨別ngine.js鐨勬簮鐮?