在 openJDK(jdk-6u23) 中,AbstractSelectableChannel.register() 的实现如下:
它首先检查此通道是否打开。然后使用 reg lock 进行注册工作。但是如果我们在 isOpen() 测试和同步块之间调用 close 方法,通道将被关闭。然后我们将注册一个 CLOSED带有选择器的频道……但这对吗?
public final SelectionKey register(Selector sel, int ops,
Object att)
throws ClosedChannelException
{
if (!isOpen())
throw new ClosedChannelException();
if ((ops & ~validOps()) != 0)
throw new IllegalArgumentException();
synchronized (regLock) {
if (blocking)
throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel);
if (k != null) {
k.interestOps(ops);
k.attach(att);
}
if (k == null) {
// New registration
k = ((AbstractSelector)sel).register(this, ops, att);
addKey(k);
}
return k;
}
}