【问题标题】:Netty ThreadRenamingRunnableNetty ThreadRenamingRunnable
【发布时间】:2013-12-30 08:46:54
【问题描述】:

我很难弄清楚如何使用 ThreadRenamingRunnable 重命名 netty 中的工作线程。我是 netty 新手,使用的是 netty 3.9.0-Final。

我想重命名工作线程...“New I/O worker #X”。老板线程的名字我没问题。

这是一个用“pong”响应“ping”的基本服务器。

public class NettyPingPong {

    public static void main(String[] args) {
        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(),
                Executors.newCachedThreadPool()));

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(
                        new LineBasedFrameDecoder(255,true,true),
                        new PongUpstreamHandler(),
                        new StringEncoder());

            }
        });

        bootstrap.bind(new InetSocketAddress(8899));
            out.println("im ready");
        }
    }

public class PongUpstreamHandler extends SimpleChannelUpstreamHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {

        ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
        String message = new String(buffer.array());
        if (message.equalsIgnoreCase("ping")){
            e.getChannel().write("pong\n");
            out.println("ponged...");
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getCause().printStackTrace();
        e.getChannel().close();
        out.println("closed...");
    }
}

【问题讨论】:

    标签: java netty


    【解决方案1】:

    1.5 年前的问题 :( 我带着同样的问题来到这里,在 Netty 3.5.0 Final 上工作。我用下面的代码解决了。

    我使用了一个线程工厂,它也会生成类似于 Abe 提到的有意义的线程名称。 而且,我将 ThreadRenamingRunnable 配置为不重命名我提供的线程。使用 ThreadFactory 并将 ThreadNameDeterminer 设置为 CURRENT。

    ThreadRenamingRunnable.setThreadNameDeterminer(ThreadNameDeterminer.CURRENT);
    

    Netty(至少 3.5.0)将 threadName 从其原始值更改为建议值“New I/O Worker #X”。上面的代码 sn-p 确保它不会改变线程名称。名称由下面的 ThreadFactory 确定。

    public class CustomThreadFactory implements ThreadFactory {
        private final AtomicInteger     threadIdSequence    = new AtomicInteger(0);
        private String                  threadNamePrefix    = "Netty-Worker-";
    
        public CustomThreadFactory() {
        }
        public CustomThreadFactory(String namePrefix) {
            this.threadNamePrefix = namePrefix;
        }
    
        @Override
        public Thread newThread(Runnable runnable) {
            Thread newThread = new Thread(runnable, threadNamePrefix + threadIdSequence.incrementAndGet());
            if (newThread.isDaemon()) {
                newThread.setDaemon(false);
            }
            if (newThread.getPriority() != Thread.NORM_PRIORITY) {
                newThread.setPriority(Thread.NORM_PRIORITY);
            }
            newThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(final Thread thread, final Throwable e) {
                    System.err.println(thread + " threw exception: " + e.getMessage());
                    e.printStackTrace();
                }
            });
            return newThread;
        }
    }
    

    【讨论】:

      【解决方案2】:

      可能有更好的方法来做到这一点,但这就是我让它工作的方式。感谢这个blog

      public class NettyPingPong {
      
          public static void main(String[] args) {
      
              final String WORKER_THREADNAME_PREFIX = "worker";
              NioWorkerPool workerPool = new NioWorkerPool(Executors.newCachedThreadPool(), 20, new ThreadNameDeterminer() {
                  @Override
                  public String determineThreadName(String currentThreadName,String proposedThreadName) throws Exception {
                      StringBuilder sb = new StringBuilder(WORKER_THREADNAME_PREFIX);
                      sb.append(currentThreadName.substring(currentThreadName.lastIndexOf('-')));
                      return sb.toString();
                  }
              });
      
              ServerBootstrap bootstrap = new ServerBootstrap(
                      new NioServerSocketChannelFactory(
                      Executors.newCachedThreadPool(),
                      workerPool));
      
              bootstrap.setPipelineFactory(
                      new ChannelPipelineFactory() {
                  public ChannelPipeline getPipeline() throws Exception {
                      return Channels.pipeline(
                              new LineBasedFrameDecoder(255, true, true),
                              new PongUpstreamHandler(),
                              new StringEncoder());
      
                  }
              });
      
              bootstrap.bind(new InetSocketAddress(8899));
              out.println("im ready");
          }
      }
      

      【讨论】:

        【解决方案3】:

        你可以传入一个ThreadFactory 来命名你的线程。看看我用来命名服务器线程的ThreadFactory。下面提供的是示例用法

        serverBootstrap = new ServerBootstrap(
                                    new NioServerSocketChannelFactory(Executors
                                        .newCachedThreadPool(new NamedThreadFactory(
                                        "TCP-Server-Boss")), Executors
                                        .newCachedThreadPool(new NamedThreadFactory(
                                        "TCP-Server-Worker"))));
        

        【讨论】:

          猜你喜欢
          • 2017-08-04
          • 2019-03-18
          • 1970-01-01
          • 2015-05-23
          • 2019-02-21
          • 2015-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多