【问题标题】:Is DefaultThreadFactory itself thread-safe?DefaultThreadFactory 本身是线程安全的吗?
【发布时间】:2013-12-16 18:57:06
【问题描述】:

Java Executor 框架提供DefaultThreadFactory 用于创建线程。

DefaultThreadFactory 本身对于多线程并发使用是否安全?还是我必须注意每个线程只有一个 DefaultThreadFactory

我知道通常最好的做法是只从一个“主”线程启动新线程,但让我们假设一个预先存在的代码库。

如果答案包含对为什么您确定DefaultThreadFactory 是否是线程安全的简短解释,那就太好了。谢谢!

【问题讨论】:

    标签: java multithreading thread-safety java.util.concurrent


    【解决方案1】:

    DefaultThreadFactory#newThread(Runnable)的Oracle JDK7实现是

    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;
    }
    

    其中threadNumberAtomicInteger。没有其他对象是共享的或可变的,因此这个实现是线程安全的。

    【讨论】:

      【解决方案2】:

      文档中没有任何内容说明一种或另一种方式,但如果您查看 OpenJDK 的代码,它是线程安全的,因为唯一可变的共享状态是两个 AtomicInteger(s)

      【讨论】:

        【解决方案3】:

        @Sotirios 的回答是正确的,但我想补充一些细节。

        DefaultThreadFactory 本身对于多个线程并发使用是否安全?

        是的。正如 Sotirios 所提到的,唯一的共享状态是使用 AtomicInteger 处理的线程号。

        或者我必须注意每个线程只有一个 DefaultThreadFactory 吗?

        这有点矛盾。每个DefaultThreadFactory 都被线程池创建的所有线程使用。您不能每个线程都有一个线程工厂,但如果您愿意,可以在池之间共享线程工厂。我怀疑为每个池创建DefaultThreadFactory 的新实例的唯一原因是为每个池获取一个新的线程名称计数器。

        我知道最好只从一个“主”线程启动新线程...

        这不是任何非常复杂的多线程应用程序的常见做法。我从大量不同的类中派生出线程或线程池。我宁愿让每个班级负责自己的后台任务,然后在某个中心位置管理它们。

        为什么你确定 DefaultThreadFactory 是否是线程安全的。

        查看 Sotirios 发布的代码。如果您的问题真的是您是否必须编写线程安全工厂,那么说明java.util.concurrent 类如何使用它就足够了。这里有一个来自ThreadPoolExecutor 的小代码示例,它支持Executors 线程池。

        private Thread addThread(Runnable firstTask) {
            Worker w = new Worker(firstTask);
            Thread t = threadFactory.newThread(w);
            ...
        

        请注意,使用工厂周围没有锁定。如果您在不同的线程池中使用相同的工厂,那么多个线程当然可以同时执行它。

        【讨论】:

        • 感谢ThreadPoolExecutor 示例。如果 Doug Lea 将 DefaultThreadFactory 视为线程安全的,我也可以。:-)
        • 不相关:您从事哪些类型的项目使用如此多的自我管理并发(我从大量不同的类中派生线程或线程池)?你非常了解你的主题。
        • 你也很了解这个主题@SotiriosDelimanolis。我只是写了很多 24/365 POJO 应用程序。从来没有做过 J2EE,所以如果我想要线程,我必须编写它们。我们确实让 Jetty 自己管理:-)。我们还使用 jgroups 网络堆栈进行所有通信,以及分叉大量线程。我更想知道的是彼得的傅。喜欢了解他的高性能交易系统中的并发挑战。干杯。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        • 2015-04-18
        • 2011-10-07
        • 2012-03-02
        • 2011-10-28
        • 2023-03-14
        相关资源
        最近更新 更多