使用 Executors.defaultThreadFactory().newThread 的原因是什么?

What the reason to use Executors.defaultThreadFactory().newThread?

在我们的项目中,我遇到了以下方法:

Thread t = Executors.defaultThreadFactory().newThread(new MyRunnable(importStartedTimestamp));
t.setName("my thread");
t.start();

我错了或者第一行是

的完整模拟
Thread t = new Thread(new MyRunnable(importStartedTimestamp));

请解释第一个代码片段是否有优势。

P.S.

我不喜欢创建冗余实体。

不同之处在于 defaultThreadFactory 会创建有意义的名称,因此在调试或分析时您会看到诸如 pool-2-thread-3 之类的名称,这很容易理解。 看一下这个 http://javahowto.blogspot.com/2011/11/why-use-threadfactory.html

来自Java 7 docs ( Executors#defaultThreadFactory() )

Returns a default thread factory used to create new threads. This factory creates all new threads used by an Executor in the same ThreadGroup. If there is a SecurityManager, it uses the group of System.getSecurityManager(), else the group of the thread invoking this defaultThreadFactory method. Each new thread is created as a non-daemon thread with priority set to the smaller of Thread.NORM_PRIORITY and the maximum priority permitted in the thread group. New threads have names accessible via Thread.getName() of pool-N-thread-M, where N is the sequence number of this factory, and M is the sequence number of the thread created by this factory.

基本上这是为 ThreadGroup 创建线程的工厂接口。当然,您可以手动执行此操作(如您的第二个代码片段所示,如果您需要特殊设置,则需要多行几行),但是工厂方法旨在隐藏您可能需要的所有细节。

此外,它还消除了直接调用 new Thread() 的需要,因此您也可以使用 Runnable 及其任何子类。

此外,优先级和 daemon-属性 已重置为出厂默认值。

if (t.isDaemon())
    t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
    t.setPriority(Thread.NORM_PRIORITY);

new Thread() 将从父线程继承这些属性。大概,就是这样吧。可以从具有非默认优先级的线程或守护线程调用工厂代码。

据我所知有两个区别:

名称不同: 新线程():

Automatically generated names are of the form "Thread-"+n, where n is an integer.

默认工厂:

New threads have names accessible via Thread.getName() of pool-N-thread-M, where N is the sequence number of this factory, and M is the sequence number of the thread created by this factory.

此外,设置的优先级略有不同。新线程():

The priority of the newly created thread is set equal to the priority of the thread creating it, that is, the currently running thread.

默认工厂:

[...] with priority set to the smaller of Thread.NORM_PRIORITY and the maximum priority permitted in the thread group

这是一个没有其他人提到的:

如果您正在编写一个将被其他程序使用的库,并且如果您的库需要创建线程或线程池,那么它应该使用客户端程序提供的 ThreadFactory.

如果客户端程序选择不提供,那就是你使用Executors.defaultThreadFactory()。

为客户提供接收通知的选项of/control线程创建和提供自定义线程的选项将使您的图书馆对潜在客户更具吸引力。

newThread(Runnable r) 方法:

  1. 设置线程组
  2. 设置新线程名称
  3. 设置堆栈大小(将被忽略)
  4. 设置为守护进程(如果是守护进程)
  5. 设置优先级为Thread.NORM_PRIORITY;

来源

/**
 * The default thread factory
 */
static class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                              Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" +
                      poolNumber.getAndIncrement() +
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                              namePrefix + threadNumber.getAndIncrement(),
                              0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

你是对的。 Executors.defaultThreadFactory().newThread().start() 冗长。

ThreadFactory 的更好用例在 Executors 中。 ThreadFactory 被接受为参数,例如 newCachedThreadPool(ThreadFactory threadFactory)。在这种情况下,您可以通过更改客户端代码来更改 ThreadFactory 实例参数。