Java 异步ByTechannel的线程含义
for的Javadoc表示操作是异步进行的,但是当到达流的末尾时会发生什么呢?是否允许实现在调用read()的同一线程内触发完成处理程序?从实现的角度来看,没有理由异步执行此操作,因为我们已经知道结果。类似地,如果用户试图读入ByteBuffer,其中remaining()返回0,则我们知道读取操作必须返回0 我这样问是因为我在自己的AsynchronousByteChannel实现中遇到了竞争条件。我正在调用一个完成处理程序,该处理程序在操作完成时对自身调用notify()。然后调用以下用户代码:Java 异步ByTechannel的线程含义,java,multithreading,asynchronous,nio,completionhandler,Java,Multithreading,Asynchronous,Nio,Completionhandler,for的Javadoc表示操作是异步进行的,但是当到达流的末尾时会发生什么呢?是否允许实现在调用read()的同一线程内触发完成处理程序?从实现的角度来看,没有理由异步执行此操作,因为我们已经知道结果。类似地,如果用户试图读入ByteBuffer,其中remaining()返回0,则我们知道读取操作必须返回0 我这样问是因为我在自己的AsynchronousByteChannel实现中遇到了竞争条件。我正在调用一个完成处理程序,该处理程序在操作完成时对自身调用notify()。然后调用以下用户代
CompletionHandler<?, ?> handler = ...;
synchronized (handler)
{
asyncByteChannel.read(handler);
handler.wait();
}
CompletionHandler=。。。;
已同步(处理程序)
{
asyncByteChannel.read(处理程序);
handler.wait();
}
注意,用户假定在操作完成时会通知处理程序,但由于read()实际上是同步调用完成处理程序的,因此它会在wait()之前得到通知,后者将永远阻塞
规范是否要求我在单独的线程中更新CompletionHandler,或者用户是否应该知道调用read()的线程可能会同步执行某些操作?即使在另一个线程上调用该处理程序,无法保证在
read
方法返回后,即在wait()
启动后调用。(好的,同步锁似乎可以保证这一点。)
对于等待和锁定,应使用同步和布尔变量:
CompletionHandler<?, ?> handler = ...;
synchronized (handler)
{
asyncByteChannel.read(handler);
while(!handler.finished) {
handler.wait();
}
}
CompletionHandler=。。。;
已同步(处理程序)
{
asyncByteChannel.read(处理程序);
而(!handler.finished){
handler.wait();
}
}
。。。然后处理程序将finished
变量设置为true。查看它们总是在单独的线程中更新CompletionHandler,但Future在同一线程中更新。搜索变量hasSpaceToRead,以查找有问题的方法
我猜他们的推理路线是这样的:
已解决:根据“如果I/O操作立即完成,并且启动线程是组中的池线程之一,那么启动线程可以直接调用完成处理程序。”如果允许我在主线程上处理CompletionHandler,您建议的解决方案将非常好。现在还不清楚是否是这样:)不,解决方案总是可用的。(如果不允许的话,这是没有必要的——但无论如何,你应该在一个循环中等待,因为可能会有虚假的唤醒。)我同意,但这不是这个问题的目的。问题在于规范是否允许在同一个线程上进行通知。它的线程模型很混乱。异步组上的javadoc不可解析。线程应该留给开发人员——这是最简单的部分。不幸的是,他们决定在这方面帮助我们。结果是非常复杂、不直观、缺乏记录(因为他们无法解释混乱)。一个不经意的评论员可能会发现API还不错——事实上,为什么它会很难呢?但当一个人认真地在上面构建一个应用程序时,其复杂性会让他发疯。