问题描述
我有一个需要执行一些业务逻辑的处理程序,我希望在一个单独的线程池中执行该处理程序,以免阻止io事件循环.我已按照 http://netty中的指定,将DefaultEventExecutorGroup添加到管道中. io/4.0/api/io/netty/channel/ChannelPipeline.html javadoc和 http://netty.io/wiki/new-and-noteworthy-in-4.0.html#no-more-executionhandler-- -其核心 Wiki:
I have a handler that needs to execute some business logic and I want that to be executed in a separate thread pool to not block the io event loop. I have added DefaultEventExecutorGroup into the pipeline as specified in http://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html javadoc and http://netty.io/wiki/new-and-noteworthy-in-4.0.html#no-more-executionhandler---its-in-the-core wiki:
ch.pipeline().addLast(new DefaultEventExecutorGroup(10), new ServerHandler());
出于测试目的,我的ServerHandler只是将当前线程置于休眠状态5秒钟:
Just for testing purposes my ServerHandler just puts the current thread to sleep for 5 seconds:
protected void channelRead0(ChannelHandlerContext ctx, Command cmd) throws Exception {
System.out.println("Starting.");
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished.");
}
但是显然,业务逻辑仍然是同步执行的:
But apparently the business logic is still executed synchronously:
Starting.
Finished.
Starting.
Finished.
Starting.
Finished.
我想念什么?
推荐答案
如果您的目标不是阻止IO事件循环-您做对了.但是由于特定于网络,您的处理程序将始终附加在EventExecutorGroup的同一线程上,因此可以预期您在上述情况下的行为.
In case your goal is not to block IO event loop - you did it right. But due to netty specific, your handler will be always attached to the same thread of EventExecutorGroup and thus behavior you described above is expected.
如果要在到达时立即并行执行阻止操作,则需要使用另一种方式-单独的ThreadPoolExecutor
.像这样:
In case you want to execute blocking operation in parallel as soon as it arrives you need to use the another way - separate ThreadPoolExecutor
. Like this:
ch.pipeline().addLast(new ServerHandler(blockingThreadPool));
其中blockingThreadPool
是常规ThreadPoolExecutor
.
例如:
ExecutorService blockingThreadPool = Executors.newFixedThreadPool(10);
现在,在您的逻辑处理程序中,您可以像这样将阻止任务提交给该执行器:
Now, within your logic handler you can submit blocking tasks to this executor like this:
protected void channelRead0(ChannelHandlerContext ctx, Command cmd) throws Exception {
blockingIOProcessor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Starting.");
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished.");
}
});
}
如果需要,您还可以将上下文传递给此可运行对象,以便在处理完成时返回响应.
You can also pass context to this runnable in order to return the response back when processing is finished if needed.
这篇关于如何使用Netty在单独的线程池中执行业务逻辑处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!