Java 的線程工廠 ThreadFactory原理及源碼詳解

在JDK的源碼使用工廠模式,ThreadFactory就是其中一種。

在我們一般的使用中,創建一個線程,通常有兩種方式:
繼承Thread類,覆蓋run方法,實現我們需要的業務
繼承Runnable接口,實現run方法,實現我們需要的業務,並且調用new Thread(Runnable)方法,將其包裝爲一個線程執行

設想這樣一種場景,我們需要一個線程池,並且對於線程池中的線程對象,賦予統一的線程優先級、統一的名稱、甚至進行統一的業務處理或和業務方面的初始化工作,這時工廠方法就是最好用的方法了

ThreadFactory接口
ThreadFactory接口很簡單,源碼如下:
public interface ThreadFactory {
    Thread newThread(Runnable r);
}

我們可以看到ThreadFactory中,只有一個newThread方法,它負責接收一個Runnable對象,並將其封裝到Thread對象中,進行執行。

最簡單的ThreadFactory實現
我們可以實現上述接口,做一個最簡單的線程工廠出來,源碼如下:

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

上述線程工廠,只是創建了一個新線程,其他什麼都沒幹。實際使用時,一般不會創建這麼簡單的線程工廠。

public class FixCountThreadFactory implements ThreadFactory{
    private final int MAX_THREAD;
    
    private final AtomicInteger count = new AtomicInteger(0);
    
    public FixCountThreadFactory(int maxThread) {
        MAX_THREAD = maxThread;
    }
    
    @Override
    public Thread newThread(Runnable r) {
        int incrementAndGet = count.incrementAndGet();
        if(incrementAndGet > MAX_THREAD)
        {
            count.decrementAndGet();
            return null;
        }
        
        return new Thread(r);
    }
}

上述線程工廠,可以控制創建線程的總數。
JDK中默認的線程工廠
在Executors工具類中,JDK提供了一個非常簡單的線程工程,源碼如下:

 static class DefaultThreadFactory implements ThreadFactory {
    static final AtomicInteger poolNumber = new AtomicInteger(1);
    final ThreadGroup group;
    final AtomicInteger threadNumber = new AtomicInteger(1);
    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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章