多執行緒 非阻塞通訊導致多次處理讀事件

2021-10-07 13:05:39 字數 2878 閱讀 4277

簡單的解釋一下,事件處理器handler有乙個handle(selectionkey)方法,根據方法的不同,執行不同的操作。對於讀事件,建立乙個執行緒進行讀事件處理。

public

class

mutithreadserver

private

static

class

eventhandler

public

void

handle

(selectionkey key)

throws ioexception

else

if(key.

isreadable()

)}private

static

class

readhandler

extends

thread

@override

public

void

run(

)catch

(ioexception e)

}//準備下一次輸入

buffer.

clear()

;}catch

(ioexception e)}}

}public

void

service()

}}catch

(ioexception e)

finally

catch

(ioexception e)}}

public

static

void

main

(string[

] args)

catch

(ioexception e)

}}

當客戶端傳送一次資料後,服務端的輸出:

可以看到,讀事件被處理了三次。

造成這個結果的原因:

事件處理速度 > 三次select()的間隔,也就是說,讀事件還在處理的時候,下一次的select()已經執行,由於讀事件還沒有完成,所以讀事件仍然是被觸發的狀態,導致了多次的處理讀事件。

產生問題的原因:事件處理速度 > select()速度

所以,增加select()之間的間隔事件。通過sleep(5000),是兩次select()之間的的間隔增加到5s

while

(selector.

select()

>0)

trycatch

(interruptedexception e)

}

通過執行緒睡眠的方式,只是驗證對問題的分析是否正確,並沒有真正的解決這個問題,通訊的資料量是不確定的,很難確定sleep()的值,況且,通過sleep()本身就與非阻塞通訊矛盾。

多次處理的原因:第二次處理事件時,不知道該事件已經被處理過了

所以,可以通過乙個標記,表示這個事件已經被處理,不需要再次處理了。

每個selectionkey,都可以繫結乙個物件,在這裡,可以繫結乙個boolean,表示是否已經被處理了。只要在處理時判斷它是否被處理了即可避免多次處理。在處理完成後,一定要把標記修改為false,否則,下乙個讀事件觸發時,就沒辦法處理了。

public

class

mutithreadserver

private

static

class

eventhandler

public

void

handle

(selectionkey key)

throws ioexception

else

if(key.

isreadable()

)//啟動乙個執行緒進行讀事件的處理

system.out.

println

("觸發讀事件");

//讀事件已經交給乙個執行緒處理

key.

attach

(boolean.true);(

newreadhandler

(key)).

start()

;}}private

static

class

readhandler

extends

thread

@override

public

void

run(

)catch

(ioexception e)

}//準備下一次輸出

buffer.

clear()

;//事件處理完成,下一次觸發該事件時,是未處理狀態

this

.selectionkey.

attach

(boolean.false);}

catch

(ioexception e)}}

}public

void

service()

}}catch

(ioexception e)

finally

catch

(ioexception e)}}

public

static

void

main

(string[

] args)

catch

(ioexception e)

}}

c 非阻塞演算法 C 多執行緒系列(6)執行緒通知

回顧一下,前面 lock monitor 部分我們學習了執行緒鎖,mutex 部分學習了程序同步,semaphor 部分學習了資源池限制。這一篇將學習 c 中用於傳送執行緒通知的 autorestevent 類。用於從乙個執行緒向另乙個執行緒傳送通知。微軟文件是這樣介紹的 表示執行緒同步事件在乙個等...

伺服器模型 從單執行緒阻塞到多執行緒非阻塞(中)

伺服器模型涉及到執行緒模式和io模式,搞清楚這些就能針對各種場景有的放矢。該系列分成三部分 單執行緒 多執行緒阻塞i o模型 單執行緒非阻塞i o模型 多執行緒非阻塞i o模型,reactor及其改進 這裡 的伺服器模型主要指的是伺服器端對i o的處理模型。從不同維度可以有不同的分類,這裡從i o的...

伺服器模型 從單執行緒阻塞到多執行緒非阻塞(上)

伺服器模型涉及到執行緒模式和io模式,搞清楚這些就能針對各種場景有的放矢。該系列分成三部分 這裡 的伺服器模型主要指的是伺服器端對i o的處理模型。從不同維度可以有不同的分類,這裡從i o的阻塞與非阻塞 i o處理的單執行緒與多執行緒角度 伺服器模型。對於i o,可以分成阻塞i o與非阻塞i o兩大...