问题描述
的 AsynchronousByteChannel.read()说,操作是异步发生,但是当流的末尾已到达发生了什么?是实现允许到调用阅读()在同一个线程内火完成处理?从实现的角度来看,没有理由要异步执行这个操作,因为我们已经知道的结果。同样地,如果用户试图读入的ByteBuffer,其中剩余的()返回我们知道0读操作必须返回0
The Javadoc for AsynchronousByteChannel.read() says the operation takes place asynchronously, but what happens when the end of stream has been reached? Is an implementation allowed to fire the completion handler within the same thread that invoked read()? From the implementation's point of view, there is no reason to carry out this operation asynchronously, because we already know the result. Similarly, if a user attempts to read into a ByteBuffer where remaining() returns 0 we know the read operation must return 0.
我问,因为我在我自己的AsynchronousByteChannel实施碰上的竞争条件。我调用调用操作完成后通知()上本身就是一个完成处理程序。然后,我引用下面的用户code:
I ask because I've run into a race condition in my own AsynchronousByteChannel implementation. I'm invoking a completion handler that invokes notify() on itself when the operation completes. I then invoke the following user code:
CompletionHandler<?, ?> handler = ...;
synchronized (handler)
{
asyncByteChannel.read(handler);
handler.wait();
}
请注意用户是假设在操作完成时的处理程序将被通报,但由于阅读()实际上调用完成处理程序同步得到它之前等待通知(),后者将永远阻塞。
Note the user is assuming that the handler will be notified when the operation completes, but because read() actually invokes the completion-handler synchronously it gets notified before wait() and the latter will block forever.
是否规范要求我在一个单独的线程来更新CompletionHandler或用户应该知道的一个事实,即调用read()将线程同步可以进行一些操作?
Does the specification require me to update CompletionHandler in a separate thread or should users be aware of the fact that the thread that invokes read() may carry out some operations synchronously?
推荐答案
看着的他们总是在一个单独的线程更新CompletionHandler,但未来在更新同一个线程。搜索变量 hasSpaceToRead
来找到问题的方法。
Looking at http://www.docjar.com/html/api/sun/nio/ch/AsynchronousSocketChannelImpl.java.html they always update CompletionHandler in a separate thread, but Future is updated in the same thread. Search for variable hasSpaceToRead
to find the method in question.
我猜他们的推理路线是这样的:
I'm guessing their line of reasoning goes something like this:
- 我们创造未来返回给用户,所以没有办法,他与它交互(同步等)我们返回的对象之前。
- 用户创建的CompletionHandler,所以我们没有控制的实施做什么的方式(我们都知道,我们有可能引发僵局!)。不要碰碰运气,火完成处理程序在一个单独的线程。
更新:我站在纠正。据如果当前线程是在该信道组的线程池则处理程序直接调用,否则是间接调用。
UPDATE: I stand corrected. According to Invoker.invoke() "If the current thread is in the channel group's thread pool then the handler is invoked directly, otherwise it is invoked indirectly."
解决:根据的 哪里的I / O操作立即完成,并发起线程组则完成处理程序可通过发起线程调用直接在池线程之一。
SOLVED: According to http://download.oracle.com/javase/7/docs/api/java/nio/channels/AsynchronousChannelGroup.html "Where an I/O operation completes immediately, and the initiating thread is one of the pooled threads in the group then the completion handler may be invoked directly by the initiating thread."
这篇关于AsynchronousByteChannel的线程含义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!