簡體   English   中英

在 Java executors 框架中用 ThreadFactory 理解 ThreadPoolExecutor

[英]Understanding ThreadPoolExecutor with ThreadFactory in Java executors framework

官方 API 文檔說:

新線程是使用ThreadFactory創建的。 如果沒有另外指定,則使用Executors.defaultThreadFactory() ,它創建的線程都在同一個ThreadGroup中,並且具有相同的NORM_PRIORITY優先級和非守護進程狀態。 通過提供不同的ThreadFactory ,您可以更改線程的名稱、線程組、優先級、守護程序狀態等。

這里的一個例子有以下幾行:

ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory, rejectionHandler);

我試圖在上述代碼的上下文中理解官方文檔中引用文本的最后一句話。 換句話說,我如何通過不同的ThreadFactory來改變線程的名稱、線程組、優先級和守護進程狀態? 這應該如何實現?

ThreadFactory是一個具有單個函數的接口, Thread newThread(Runnable r) ThreadFactory 的 Javadoc 中的示例實現:

 class SimpleThreadFactory implements ThreadFactory {
   public Thread newThread(Runnable r) {
     return new Thread(r);
   }
 }

Thread8 個不同的構造函數,允許您設置線程名稱、堆棧大小和 ThreadGroup。 它還有幾個可以調用的 setter,用於控制線程優先級、類加載器等。 甚至可能會返回 Thread 的某個子類,並帶有您選擇賦予它的任何行為。

因此,與其傳入Executors.defaultThreadFactory()的返回值,不如創建自己的返回值,並將其實例傳遞到新的ThreadPoolExecutor

ThreadFactory接口包含newThread(Runnable r)方法。 您可以實現它,以便創建的線程具有更有意義的名稱。

例如:

  private final static String THREAD_NAME_TEMPLATE = "%s-pool-%d-thread-%d";

  @Override
  public Thread newThread(Runnable r) {
    Thread t = new Thread(group, r,
      String.format(THREAD_NAME_TEMPLATE, namePrefix, poolNumber, threadNumber.getAndIncrement()),
      0);
    t.setDaemon(false);
    t.setPriority(Thread.NORM_PRIORITY);
    return t;
  }

最簡單的解決方案是復制並粘貼原始源代碼:

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

並添加您想要的更改。 為什么沒有更簡單的方法可以做到這一點,我不知道。 我想做的就是更改線程的名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM