Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用netty在单独的线程池中执行业务逻辑处理程序_Java_Multithreading_Netty_Handler - Fatal编程技术网

Java 如何使用netty在单独的线程池中执行业务逻辑处理程序

Java 如何使用netty在单独的线程池中执行业务逻辑处理程序,java,multithreading,netty,handler,Java,Multithreading,Netty,Handler,我有一个需要执行一些业务逻辑的处理程序,我希望它在单独的线程池中执行,以避免阻塞io事件循环。我已将DefaultEventExecutorGroup添加到javadoc和wiki中指定的管道中: 出于测试目的,我的ServerHandler将当前线程休眠5秒钟: protected void channelRead0(ChannelHandlerContext ctx, Command cmd) throws Exception { System.out.println("Starti

我有一个需要执行一些业务逻辑的处理程序,我希望它在单独的线程池中执行,以避免阻塞io事件循环。我已将DefaultEventExecutorGroup添加到javadoc和wiki中指定的管道中:

出于测试目的,我的ServerHandler将当前线程休眠5秒钟:

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.");        
}
但显然,业务逻辑仍然是同步执行的:

Starting.
Finished.
Starting.
Finished.
Starting.
Finished.

我遗漏了什么?

因为
Netty
处理同一个
EventExecutor
从同一个套接字发送的请求,所以您可以启动多个客户端,并查看结果。

如果您的目标不是阻止IO事件循环,那么您做得对了。但由于特定于netty,您的处理程序将始终连接到EventExecutorGroup的同一线程,因此您需要上述行为

如果您希望在阻塞操作到达后立即并行执行,则需要使用另一种方法-分离
ThreadPoolExecutor
。像这样:

ch.pipeline().addLast(new ServerHandler(blockingThreadPool));
其中
blockingThreadPool
是常规
ThreadPoolExecutor

例如:

ExecutorService blockingThreadPool = Executors.newFixedThreadPool(10);
现在,在逻辑处理程序中,您可以向该执行器提交阻塞任务,如下所示:

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.");
        }
    });

}

如果需要,您还可以将上下文传递到此runnable,以便在处理完成时返回响应。

是否可以将每个新请求作为提交到线程池的单独任务处理,而不为每个套接字分配线程?我希望来自同一个客户端的请求也能并行运行。@TTT您可以将
命令
实例放入方法
channelRead
上的
BlockingQueue
容器中,然后在其他线程上的您自己的executor服务中处理它。嗯,当然,我总是可以手动完成这项工作,但有没有什么烦人的方法来完成这项工作呢?既然我可以将EventExecutorGroup传递给我的管道处理程序,那么我是否可以告诉它不要使用每套接字一个线程的方法?@TTT netty方法就是您在自己的代码中所采用的方法。如果您的目标不是阻止IO线程,那么您做得对。如果您希望在阻塞任务到达后立即并行执行,则需要创建单独的线程池。他是否应该重用EventExecutorGroup,并且不要在每次将处理程序添加到管道时都创建一个新的线程池?@Eric这取决于业务逻辑。一般来说,是的,他不应该。
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.");
        }
    });

}