Is the following code thread-safe? If so, what guarantees the safe publication of the ByteBuffer
instance to the thread executing the 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) {
//...
}
});
an authoritative reference that is valid for all JVMs and all platforms
The only such authoritative source I know of is javadocs (1, 2, 3).
Unfortunately, as you can see for yourself, they contain no explicit and clear guarantees of thread-safety.
It means the code is not thread-safe.
IMO the guarantees should be given in the javadoc for the method, the method's class, or CompletionHandler
— then we can be sure they are implemented for all JVMs and all platforms (and will stay implemented in the future).
But if you really want, you can "compile" a proof for thread-safety from multiple places in different javadocs:
AsynchronousSocketChannel.read(...)
:
The handler parameter is a completion handler that is invoked when the read operation completes (or fails).
java.nio.channels
:
Asynchronous channels are bound to an asynchronous channel group for the purpose of resource sharing. A group has an associated ExecutorService to which tasks are submitted to handle I/O events and dispatch to completion handlers that consume the result of asynchronous operations performed on channels in the group.
ExecutorService
:
Memory consistency effects: Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task
As a result, we get that every action of the I/O read to ByteBuffer
happens-before the first action of CompletionHandler
=> this means the code is thread-safe.
IMO "compiled proofs" like the one above are too fragile, and personally I would assume that the code is not thread-safe.