上下文:Netty 3.6.3.Final,Java 1.7,Scala 2.9.x
为了最小化(可能是空闲的)线程的数量,我想与不同的NIO套接字通道工厂(TCP)和一个NioDatagramChannelFactory共享NIO客户端/服务器和工作池。我使用至少两个(或三个与Finagle堆栈)的服务器/客户端引导集,每个都有自己的NIO套接字通道工厂。为每个boss和worker池使用一个新的缓存线程池会导致大量时间没有使用的线程负载。粗略的目标是将所有bootstraps / channel工厂的工作人员数限制为2 * CPU核心数和老板数到CPU核心数。
我正在尝试切换到NioServer / ClientBossPool和NioWorkerPool,用于我自己的一组bootstrap。但是根据底层ThreadPoolExecutor的配置,关闭引导程序会导致主线程在AbstractNioSelector关闭锁存器上永远等待。
class NioClientBossPoolTest {
@Test def shutdown() {
val corePoolSize = 1
val maxPoolSize = Integer.MAX_VALUE
val keepAliveSeconds = 60
val keepAliveUnit = TimeUnit.SECONDS
val blocking = true
val queue: BlockingQueue[Runnable] =
if(blocking) new LinkedBlockingQueue[Runnable](Integer.MAX_VALUE)
else new SynchronousQueue[Runnable]()
val executor = new ThreadPoolExecutor(corePoolSize,
maxPoolSize,
keepAliveSeconds,
keepAliveUnit,
queue)
val clientBossPool = new NioClientBossPool(executor, 1) // B
new NioServerBossPool(executor, 1) // C
val workerPool = new NioWorkerPool(executor, 1) // A
val channelFactory = new NioClientSocketChannelFactory(clientBossPool, workerPool)
val bootstrap = new ClientBootstrap(channelFactory)
// hangs waiting for shutdown latch in AbstractNioSelector (NioWorker or NioClientBoss
// depending on the order of statement A, B, C) for
// LinkedBlockingQueue, corePoolSize = 1 and sequence of statements A, B and C other than [B, A, C]
// LinkedBlockingQueue, corePoolSize = 2 and sequence of statements A, B and C other than
// [A, B, C], [B, C, A] and [C, B, A]
bootstrap.shutdown()
}
}
我很确定执行程序服务配置必须满足某些特定要求,但哪些(核心池大小,队列类型)? bootstrap.shutdown()将永远阻塞,除非语句A,B和C的执行顺序正好是[B,A,C]。将核心池大小增加到2个块,用于三个语句的六个组合中的三个。核心池大小> 2或使用SynchronousQueue,每个组合终止。
答案 0 :(得分:0)
实际上这似乎是一个错误。我认为如果xou为boss和workerpool使用不同的执行程序,它会起作用。你能打开一个bug报告吗?