Javadoc 的AsynchronousByteChannel.read() http://download.oracle.com/javase/7/docs/api/java/nio/channels/AsynchronousByteChannel.html#read%28java.nio.ByteBuffer,%20A,%20java.nio.channels.CompletionHandler%29说操作是异步发生的,但是当到达流末尾时会发生什么?是否允许实现在调用 read() 的同一线程中触发完成处理程序?从实现的角度来看,没有理由异步执行此操作,因为我们已经知道结果。类似地,如果用户尝试读取剩余()返回 0 的 ByteBuffer,我们知道读取操作必须返回 0。
我问这个问题是因为我在自己的 AsynchronousByteChannel 实现中遇到了竞争条件。我正在调用一个完成处理程序,当操作完成时,该处理程序会自行调用notify()。然后我调用以下用户代码:
CompletionHandler<?, ?> handler = ...;
synchronized (handler)
{
asyncByteChannel.read(handler);
handler.wait();
}
请注意,用户假设操作完成时将通知处理程序,但由于 read() 实际上同步调用完成处理程序,因此它会在 wait() 之前收到通知,而后者将永远阻塞。
规范是否要求我在单独的线程中更新 CompletionHandler 或者用户是否应该意识到调用 read() 的线程可能会同步执行某些操作?
即使在另一个线程上调用处理程序,也不能保证它会被调用after the read
方法返回,即在您之后wait()
开始了。 (好吧,同步锁似乎保证了这一点。)
您应该使用同步和布尔变量来等待和锁定:
CompletionHandler<?, ?> handler = ...;
synchronized (handler)
{
asyncByteChannel.read(handler);
while(!handler.finished) {
handler.wait();
}
}
...然后你的处理程序将设置finished
变量为真。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)