Mal*_*alt 6 java java-memory-model nio2
以下代码是线程安全的吗?如果是这样,什么保证将ByteBuffer实例安全发布到执行 的线程CompletionHandler?
AsynchronousSocketChannel channel = ...
ByteBuffer buf = ByteBuffer.allocate(1024);
channel.read(buf, null, new CompletionHandler<Integer, Void>() {
//"completed" can be executed by a different thread than channel.read()
public void completed(Integer result, Void attachment) {
buf.flip(); //Can buf be safely accessed here? If so, why?
//...
}
public void failed(Throwable exc, Void attachment) {
//...
}
});
Run Code Online (Sandbox Code Playgroud)
小智 3
\n\n对所有 JVM 和所有平台都有效的权威参考
\n
我所知道的唯一这样的权威来源是 javadocs ( 1 , 2 , 3 )。
\n不幸的是,正如您亲眼所见,它们不包含明确且明确的线程安全保证。
\n这意味着代码不是线程安全的。
\nIMO 应该在method、method\'s class或\xe2\x80\x94的 javadoc 中给出保证CompletionHandler,然后我们可以确定它们针对所有 JVM 和所有平台实现(并将在将来保持实现) 。
但如果您确实愿意,您可以从不同 javadoc 中的多个位置“编译”线程安全证明:
\nAsynchronousSocketChannel.read(...):\n\n\nhandler 参数是读取操作完成(或失败)时调用的完成处理程序。
\n
java.nio.channels:\n\n\n异步通道绑定到异步通道组,以达到资源共享的目的。组具有关联的 ExecutorService,任务将提交到该 ExecutorService 以处理 I/O 事件并分派到完成处理程序,这些完成处理程序消耗在组中的通道上执行的异步操作的结果。
\n
ExecutorService:\n\n\n内存一致性影响:将 Runnable 或 Callable 任务提交给 ExecutorService 之前线程中的操作发生在该任务采取的任何操作之前
\n
结果,我们得到 I/O 读取的每个操作都发生在 =>的第一个操作ByteBuffer 之前CompletionHandler,这意味着代码是线程安全的。
IMO 像上面这样的“编译证明”太脆弱了,我个人认为代码不是线程安全的。
\n