Netty OrderedMemoryAwareThreadPoolExecutor没有创建多个线程

时间:2013-02-07 22:53:01

标签: multithreading netty persistent-connection threadpoolexecutor

我将Netty用于多线程TCP服务器和单个客户端持久连接。 客户端发送许多二进制消息(在我的用例中为10000),并且应该接收每条消息的答案。我在管道中添加了一个OrderedMemoryAwareThreadPoolExecutor来处理多个线程上DB调用的执行。

如果我在方法messageReceived()中运行数据库调用(或使用Thread.currentThread()模拟它(sleep(50)),那么所有事件都由单线程处理。

    5 count of {main}
    1 count of {New
10000 count of {pool-3-thread-4}

对于messageReceived()的简单实现,服务器按预期创建许多执行程序线程。

我应该如何配置ExecutionHandler以获取业务逻辑的多个线程执行程序?

这是我的代码:

public class MyServer {

      public void run() {
            OrderedMemoryAwareThreadPoolExecutor eventExecutor = new OrderedMemoryAwareThreadPoolExecutor(16, 1048576L, 1048576L, 1000, TimeUnit.MILLISECONDS, Executors.defaultThreadFactory());  
            ExecutionHandler executionHandler = new ExecutionHandler(eventExecutor);        
            bootstrap.setPipelineFactory(new ServerChannelPipelineFactory(executionHandler));
      }
    }  



    public class ServerChannelPipelineFactory implements ChannelPipelineFactory {

      public ChannelPipeline getPipeline() throws Exception {

        pipeline.addLast("encoder", new MyProtocolEncoder());
        pipeline.addLast("decoder", new MyProtocolDecoder());
        pipeline.addLast("executor", executionHandler);
        pipeline.addLast("myHandler", new MyServerHandler(dataSource));

      }
    }

    public class MyServerHandler extends SimpleChannelHandler {

      public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) throws DBException {


          // long running DB call simulation
          try {
            Thread.currentThread().sleep(50);
          } catch (InterruptedException ex) {

          }  

          // a simple message  
          final MyMessage answerMsg = new MyMessage();
          if (e.getChannel().isWritable()) {
            e.getChannel().write(answerMsg);
          }  
      }      
    }

1 个答案:

答案 0 :(得分:3)

OrderedMemoryAwareThreadPoolExecutor保证按顺序处理来自单个通道的事件。您可以将其视为将通道绑定到池中的特定线程,然后处理该线程上的所有事件 - 尽管它比这更复杂,因此不要依赖于始终由同一线程处理的通道。

如果启动第二个客户端,您将看到它(很可能)正在池中的另一个线程上处理。如果您真的可以并行处理单个客户端的请求,那么您可能需要MemoryAwareThreadPoolExecutor但请注意,这不能保证通道事件的顺序。