J'ai lu Guide Netty, il n'explique pas beaucoup sur ChannelFuture
. Je suis confus pourquoi cela ne provoquera pas une impasse.Comment Netty ChannelFuture notifier ne provoque pas le verrouillage
1.Il m'apprend à démarrer un serveur comme celui-ci.
ServerBootstrap sb = new ServerBootstrap();
sb.group(bossGroup, workerGroup);
sb.channel(NioServerSocketChannel.class);
sb.localAddress(new InetSocketAddress(port));
sb.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new BigGameMessageDecoder(msgRegistry));
ch.pipeline().addLast(BIG_MSG_ENCODER);
if (isDebug) {
ch.pipeline().addLast(MSG_LOGGER);
}
ch.pipeline().addLast(new GameMessageHandler<>(msgRegistry,
sessionFactory.createGameSession(), event, false));
}
});
ChannelFuture cf = sb.bind().sync();
logger.error("start server at port: {}", port);
if (sync) {
cf.channel().closeFuture().sync();
}
En ligne:
ChannelFuture cf = sb.bind().sync();
sb.bind()
retourne un ChannelFuture
et sync()
attendra que ce futur isDone.
Je lis le code DefaultChannelGroupFuture
, il me montre à sync()
appelle await()
en effet. Et await()
se verrouiller, attendez que d'autres notifier.
Et dans la fonction ChannelFuture
setSuccess
il essaie d'obtenir à nouveau ce verrou. Donc, ma question est si sync()
obtient le verrou en premier, puis attend et ChannelFuture
essaie de notifier, mais il ne peut pas obtenir le verrou. Cela va-t-il provoquer une impasse?
Si non, comment
ChannelFuture
peut-il notifier d'autres écouteurs?D'autres livres me dit N'UTILISER
sync()
ouawait()
dansChannelHandler
car cela pourrait provoquer une impasse. Pourquoi? Quelle est la différence entre les questions 1 et 3?
public DefaultChannelGroupFuture sync() throws InterruptedException {
super.sync();
return this;
}
public Promise<V> sync() throws InterruptedException {
await();
rethrowIfFailed();
return this;
}
public Promise<V> await() throws InterruptedException {
if (isDone()) {
return this;
}
if (Thread.interrupted()) {
throw new InterruptedException(toString());
}
synchronized (this) {
while (!isDone()) {
checkDeadLock();
incWaiters();
try {
wait();
} finally {`enter code here`
decWaiters();
}
}
}
return this;
}
public Promise<V> setSuccess(V result) {
if (setSuccess0(result)) {
notifyListeners();
return this;
}
throw new IllegalStateException("complete already: " + this);
}
private boolean setSuccess0(V result) {
if (isDone()) {
return false;
}
synchronized (this) {
// Allow only once.
if (isDone()) {
return false;
}
if (result == null) {
this.result = SUCCESS;
} else {
this.result = result;
}
if (hasWaiters()) {
notifyAll();
}
}
return true;
}
Donc si dans ma méthode channelHandler 'channelInactive' essayez de reconnecter la synchronisation comme ceci' bootstrap.connect(). Sync(); 'Le' bootstrap' est le strap pour connecter le serveur. Par notre conclusion ci-dessus, il va jeter une exception par certains. Mais en réalité, l'occurrence d'une exception est fortuite. 'io.netty.util.concurrent.BlockingOperationException: DefaultChannelPromise @ 3b72750a (incomplet) à l'adresse io.netty.util.concurrent.DefaultPromise.checkDeadLock (DefaultPromise.java:380) ~ [netty-all-4.0.13.Final. jar: 4.0.13.Final] à io.netty.channel.DefaultChannelPromise.checkDeadLock (DefaultChann' – wangcaicai
@ user8119590 en raison de l'awai() pas attendre le verrou une fois l'opération terminée.vous pouvez exécuter le code 'bootstrap.connect() .channel(). closeFuture(). sync() ', et voir ce qu'il s'est passé – dabaicai
Je l'ai compris, cela dépend si l'avenir de' bootstrap.connect() 'répondra rapidement ou non.) 'if' isDone() 'retourne la méthode' true' va retourner, donc il n'y a pas d'exception Et si 'isDone()' retourne 'false' alors la méthode va vérifier le blocage. @dabaicai – wangcaicai