前面(http://san-yun.iteye.com/blog/1693598)提到netty通过ChannelFuture来提供异步IO,但我实际测试中发现并不是总是这样的,需要ChannelPipelineFactory中指定ExecutionHandler。测试代码:
@ChannelPipelineCoverage("all") public class DiscardServerHandler extends SimpleChannelHandler { public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { Channel channel =e.getChannel(); ChannelFuture future = channel.write(e.getMessage()); future.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { Thread.sleep(1000); System.out.println(Thread.currentThread().getName()); System.out.println("ok1"); } }); System.out.println(Thread.currentThread().getName()); System.out.println("ok2"); }
package com.duitang.test.test; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; public class NettyTest { public static void main(String[] args) throws SecurityException, Exception { ChannelFactory factory = new NioServerSocketChannelFactory ( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap bootstrap = new ServerBootstrap (factory); DiscardServerHandler handler = new DiscardServerHandler(); ChannelPipeline pipeline = bootstrap.getPipeline(); pipeline.addLast("handler", handler); bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.keepAlive", true); bootstrap.bind(new InetSocketAddress(8080)); } }
输出ok1,ok2,同步执行。
public static void main(String[] args) { ChannelFactory factory = new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap bootstrap = new ServerBootstrap(factory); ExecutionHandler executionHandler = new ExecutionHandler( new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576)); DatabaseGatewayPipelineFactory gatewayPipelineFactory = new DatabaseGatewayPipelineFactory( executionHandler); bootstrap.setPipelineFactory(gatewayPipelineFactory); bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.keepAlive", true); bootstrap.bind(new InetSocketAddress(8080)); } static class DatabaseGatewayPipelineFactory implements ChannelPipelineFactory { private final ExecutionHandler executionHandler; public DatabaseGatewayPipelineFactory(ExecutionHandler executionHandler) { this.executionHandler = executionHandler; } public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addFirst("decoder", new DiscardServerHandler()); pipeline.addFirst("encoder", new DiscardServerHandler()); pipeline.addFirst("executor", executionHandler); pipeline.addLast("handler", new DiscardServerHandler()); return pipeline; } }
输出
pool-3-thread-2
ok2
New I/O server worker #1-1
ok1