似乎在实现依赖 java nio 的服务器时,以下做法是标准的:
使用单个线程(和单个选择器)进行读取:
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()
是的,我省略了大量代码
我的问题不是关于从通道中选择/读取的机制,而是在单独的线程而不是选择器线程中读取#buffer 的可见性语义。我在 javadoc 中看不到任何内容,说明从线程 A(上面的“处理程序”)中的 ByteBuffer 读取可以保证看到对线程 B 中的 ByteBuffer 的写入(上面的“选择器”)。
现在,在我看来,上面的代码根本不是多线程安全的,即它是错误的。但是我在许多教程甚至一些代码库中都看到了相同的模式(甚至总是没有提到可见性问题);所以我想知道我是否遗漏了一些明显的东西。
注意:我特别关注“处理程序”线程仅从#buffer读取的情况 - 它从不向其中写入新字节