http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?r1=1069292&r2=1135026&diff_format=h
在这里我可以看到最近添加了超时
确保 startTimeout 大于 0 否则您将 wait(0) 或 wait(-n) 这可能会导致 IllegalMonitorStateException
编辑:好的,上面是一场灾难,但让我们试试这个:
我们在 Mux 构造函数中:http: //svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java ?view=markup
第 176 行我们创建了 SocketChannelConnectionIO 并传递了它,然后我们中断并由不同的线程接管。
在此处定义的 SocketChannelConnectionIO 的构造函数中:http: //svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/SocketChannelConnectionIO.java ?view=markup
line 112 我们注册使用新的处理程序()进行通道。
处理程序在 chanel 和函数上接收到一些东西,让我们说函数 handleReadReady 被执行,我们在 muxLock 上同步。
现在我们仍在构造函数中,所以 final 中的对象仍然是可变的!!!假设它发生了变化,现在我们有一些东西在等待不同的 muxLock
百万分之一的场景
编辑
http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?revision=1135026&view=co
Mux(SocketChannel channel,
int role, int initialInboundRation, int maxFragmentSize)
throws IOException
{
this.role = role;
if ((initialInboundRation & ~0x00FFFF00) != 0) {
throw new IllegalArgumentException(
"illegal initial inbound ration: " +
toHexString(initialInboundRation));
}
this.initialInboundRation = initialInboundRation;
this.maxFragmentSize = maxFragmentSize;
//LINE BELOW IS CAUSING PROBLEM it passes this to SocketChannelConnectionIO
this.connectionIO = new SocketChannelConnectionIO(this, channel);
//Lets assume it stops here we are still in constructor
//and we are not in synchronized block
directBuffersUseful = true;
}
现在在 SocketChannelConnectionIO
http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/SocketChannelConnectionIO.java?revision=1069292&view=co的构造函数中
SocketChannelConnectionIO(Mux mux, SocketChannel channel)
throws IOException
{
super(mux);
channel.configureBlocking(false);
this.channel = channel;
//Line below we are registering to the channel with mux that is still mutable
//this is the line that actually is causing the problem move that to
// start() and it should work
key = selectionManager.register(channel, new Handler());
}
将此代码移动到 start() 应该可以工作key = selectionManager.register(channel, new Handler());
(我假设 start 在我们想要开始处理时执行)
/**
* Starts processing connection data.
*/
void start() throws IOException {
key = selectionManager.register(channel, new Handler());
key.renewInterestMask(SelectionKey.OP_READ);
}
但是最好不要在 mux 的构造函数中创建 SocketChannelConnectionIO 但也许在那之后的某个地方与第二个构造函数创建 StreamConnectionIO 相同