看來,在執行依賴於Java NIO的服務器,下面的做法是標準:NIO和跨線程的ByteBuffers知名度
使用一個線程(和一個選擇器)用於讀取:
ByteBuffer buffer = . . .
selector.select()
...
channel.read(buffer)
if (isRequestComplete(buffer))
processRequest(buffer) //will run in a separate thread
void processRequest(ByteBuffer buffer)
new Thread(new Handler(buffer)).start()
是的,我elliding的代碼大量
我的問題是不是選擇/從通道讀取的機制,而是#buffer的知名度語義被讀入一個單獨的線程比選擇線。我在javadoc中沒有看到任何內容,聲明從線程A(上面的'Handler')中的ByteBuffer讀取可以看到寫入線程B中的ByteBuffer(上面的'選擇器')。
現在,在我看來,上面的代碼根本不是多線程安全的,即它是錯誤的。 但我在許多教程甚至一些代碼庫中都看到過相同的模式(始終沒有引用可視性關注);所以我想知道我是否錯過了一些明顯的東西。
注:我專門側重於在「處理程序」主題永遠只從#buffer讀取情況 - 它從來沒有寫入新的字節到它
是的,非常好的一點。 – igaz 2013-03-17 06:24:38
是的,出色的一點。事實上,另一種解釋我的問題的方法是「在哪裏發生 - 之前」?我已經忘記了有關創建/啓動線程的JMM。顯然,你也可以使用ConcurrentQueues,顯式同步(blecch)和ExecutorService.execute(new Handler(buffer))等等 - 都應該足夠了。 – igaz 2013-03-17 06:31:58