我正在尝试关闭已打开连接的 Netty 服务器,但它只是挂起。这就是我所做的。
我已经在关闭 ChannelGroup 的服务器上注册了一个关闭钩子,并在 ServerBootstrap 上调用 releaseExternalResources(或者实际上我正在使用 protobuf-pro-duplex 库的 DuplexTcpServerBootstrap 来做到这一点)。无论如何,关机钩子在关机时被正确调用,但它永远不会返回。当我对正在发生的事情进行线程转储时,我可以看到两个有趣的堆栈:
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006b0890950> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1433)
at org.jboss.netty.util.internal.ExecutorUtil.terminate(ExecutorUtil.java:103)
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.releaseExternalResources(AbstractNioWorkerPool.java:80)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.releaseExternalResources(NioServerSocketChannelFactory.java:162)
at org.jboss.netty.bootstrap.Bootstrap.releaseExternalResources(Bootstrap.java:319)
at com.googlecode.protobuf.pro.duplex.server.DuplexTcpServerBootstrap.releaseExternalResources(DuplexTcpServerBootstrap.java:132)
at com.xxx.yyy.node.NodeServer$2.run(NodeServer.java:104)
at java.lang.Thread.run(Thread.java:722)
Run Code Online (Sandbox Code Playgroud)
所以这是永远不会返回的关闭钩子线程。下面是另一个似乎正在等待通道的线程:
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.interrupt(Native Method)
at sun.nio.ch.EPollArrayWrapper.interrupt(EPollArrayWrapper.java:274)
at sun.nio.ch.EPollSelectorImpl.wakeup(EPollSelectorImpl.java:193)
- locked <0x00000006b0896660> (a java.lang.Object)
at java.nio.channels.spi.AbstractSelector$1.interrupt(AbstractSelector.java:210)
at java.nio.channels.spi.AbstractSelector.begin(AbstractSelector.java:216)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:80)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
- locked <0x00000006b08964a8> (a sun.nio.ch.Util$2) …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码,该代码计算列表中每个字符串的频率,并将结果存储在可变映射中.这很好用,但我不明白+ =方法的定义在哪里?!这是一些奇怪的隐式转换事物还是什么?我在某处看到了这段代码,但它没有包含对+ =的解释.
val list = List("a", "b", "a")
val counts = new scala.collection.mutable.HashMap[String, Int]().withDefaultValue(0)
list.foreach(counts(_) += 1)
counts
//> res7: scala.collection.mutable.Map[String,Int] = Map(a -> 2, b -> 1)
Run Code Online (Sandbox Code Playgroud)
map的apply会返回一个Int,但是Int没有+ =并且这个方法用一个新值更新map,所以看起来apply会返回一个带有+ =方法的可变整数...