NIO2 CompletionHandler线程安全性及ByteBuffer安全发布问题
结论
这段代码是线程安全的,completed方法中可以安全访问ByteBuffer实例buf。
安全发布的保障机制
主要来自Java异步IO规范和语言特性两层的强制约定:
- 首先是
java.nio.channels异步通道的Happens-Before规范保证:JDK明确要求,调用异步IO操作(比如这里的read方法)的线程中,对传入缓冲区的所有操作,Happens-Before于对应CompletionHandler的completed或failed方法的执行。异步IO的底层实现(比如线程池任务提交、内核事件分发逻辑)会自动做好内存屏障的处理,保证原线程对buf的初始化状态对执行回调的线程完全可见,不会出现半初始化的内存可见性问题。 - 其次是Java匿名内部类的捕获变量规则:代码里
buf是匿名CompletionHandler捕获的外部局部变量,符合*有效不可变(Effectively Final)*要求(初始化后没有修改过引用指向)。匿名内部类实例化时会把捕获的变量存储为自身的实例字段,而把CompletionHandler提交给异步IO框架的动作本身就带有Happens-Before语义,进一步保证了内部类持有的buf引用和对应对象状态对回调线程可见。
只要你在调用channel.read()之后没有在原调用线程继续修改buf的内容、position、limit等属性,回调线程里的访问就是完全安全的,不需要额外加同步。
内容的提问来源于stack exchange,提问作者Malt
相关产品推荐
相关产品推荐

