假设我有一个利用Executor框架的应用程序

Executors.newSingleThreadExecutor().submit(new Runnable(){
    @Override
    public void run(){
        // do stuff
    }
}

当我在调试器中运行此应用程序时,将创建一个具有以下(默认)名称的线程:thread [pool-1-thread-1]。正如您所看到的,这并不是非常有用,而且据我所知,Executor框架并没有提供一种简单的方法来命名创建的线程或线程池。

那么,如何为线程/线程池提供名称呢?例如,Thread[fopool - foothread]。


当前回答

我发现,如果您只是想更改单个线程执行器的名称,那么使用lambda作为线程工厂是最简单的。

Executors.newSingleThreadExecutor(runnable -> new Thread(runnable, "Your name"));

其他回答

我用来装饰现有工厂的自制核心Java解决方案:

public class ThreadFactoryNameDecorator implements ThreadFactory {
    private final ThreadFactory defaultThreadFactory;
    private final String suffix;

    public ThreadFactoryNameDecorator(String suffix) {
        this(Executors.defaultThreadFactory(), suffix);
    }

    public ThreadFactoryNameDecorator(ThreadFactory threadFactory, String suffix) {
        this.defaultThreadFactory = threadFactory;
        this.suffix = suffix;
    }

    @Override
    public Thread newThread(Runnable task) {
        Thread thread = defaultThreadFactory.newThread(task);
        thread.setName(thread.getName() + "-" + suffix);
        return thread;
    }
}

在行动:

Executors.newSingleThreadExecutor(new ThreadFactoryNameDecorator("foo"));

你可以提供一个ThreadFactory给newSingleThreadScheduledExecutor(ThreadFactory)。工厂将负责创建线程,并能够为它们命名。

引用Javadoc的话:

Creating new threads New threads are created using a ThreadFactory. If not otherwise specified, a Executors.defaultThreadFactory() is used, that creates threads to all be in the same ThreadGroup and with the same NORM_PRIORITY priority and non-daemon status. By supplying a different ThreadFactory, you can alter the thread's name, thread group, priority, daemon status, etc. If a ThreadFactory fails to create a thread when asked by returning null from newThread, the executor will continue, but might not be able to execute any tasks

番石榴几乎总有你需要的东西。

ThreadFactory namedThreadFactory = 
  new ThreadFactoryBuilder().setNameFormat("my-sad-thread-%d").build()

并将它传递给您的ExecutorService。

你也可以在线程执行之后更改线程的名称:

Thread.currentThread().setName("FooName");

例如,如果您在不同类型的任务中使用相同的ThreadFactory,这可能会很有趣。

我想我要抛出一些简单的例子,只是为了让选项都在那里:

唯一的数字(也可以把它放到一个方法中):

AtomicInteger threadNum = new AtomicInteger(0);
ExecutorService e = Executors.newSingleThreadExecutor(r -> new Thread(r, "my-name-" + threadNum.incrementAndGet()));

唯一的编号和“可能”唯一的名称(如果您正在生成新的Runnable对象)。如果启动线程是在一个被多次调用的方法中,例如:

AtomicInteger threadNum = new AtomicInteger(0);
ExecutorService e = Executors.newSingleThreadExecutor(r -> new Thread(r, "my-name-" + threadNum.incrementAndGet() + "-" + r.hashCode()));

如果你真的想每次都有一个唯一的名字,你就需要一个带有静态变量的类(也可以在那里添加一个静态池号前缀,参见其他答案)。

在JDK < 8中等价(你不需要一个新的类,或者可以从一个方法中返回一个ThreadFactory):

Executors.newSingleThreadExecutor(new ThreadFactory() {
      AtomicInteger threadCount = new AtomicInteger(0);

      @Override
      public Thread newThread(Runnable r) {
        return new Thread(r, "your-name-" + threadCount.getAndIncrement() + "-" + r.hashCode()); // could also use Integer.toHexString(r.hashCode()) for shorter
      }
    }));

并且可以将其作为变量,作为“you-name-”方面的方法。或者像其他答案一样,使用一个单独的带有构造函数的类。