關於線程的使用問題,使用(ThreadPoolExecutor)

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,
NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue,
new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());
//執行任務
executorService.execute(new Runnnable() {
...
});

避免使用:
new Thread(new Runnable() {
@Override
public void run() {
//操作語句
...
}
}).start();

避免使用匿名內部類。不利於線程回收,銷燬,創建

建議使用線程池。 但是關於線程池創建配置,有一些疑慮:

 

引用別人說的話:

對於CPU密集型計算,多線程本質上是提升多核CPU的利用率,所以對於一個4核的CPU,每個核一個線程,理論上創建4個線程就可以了,再多創建線程也只是增加線程切換的成本。所以,對於CPU密集型的計算場景,理論上“線程的數量=CPU核數”就是最合適的。不過在工程上,線程的數量一般會設置爲“CPU核數+1”,這樣的話,當線程因爲偶爾的內存頁失效或其他原因導致阻塞時,這個額外的線程可以頂上,從而保證CPU的利用率。

 

此處附上本人設計的線程池工具類

public class ThreadPoolUtil {
    /**
     * CPU核心數
     */
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();

    // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work
    /**
     * 核心線程數,會一直存活,即使沒有任務,線程池也會維護線程的最少數量
     */
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));

    /**
     * 線程池維護線程的最大數量
     */
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;

    /**
     * 線程池維護線程所允許的空閒時間
     */
    private static final int KEEP_ALIVE_SECONDS = 30;

    /**
     *線程池維護線程所允許的空閒時間單位
     */
    private static final TimeUnit UNIT = TimeUnit.SECONDS;

    /**
     * 線程工廠,爲線程池提供創建新線程的功能
     */
    private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "ChangeMax Thread #" + mCount.getAndIncrement());
        }
    };

    /**
     * 線程池中的任務隊列,通過線程池的execute方法提交的Runnable對象會存儲在這個參數中
     */
    private static final BlockingQueue<Runnable> TASK_QUEUE = new LinkedBlockingQueue<>(128);

    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    private static final Executor THREAD_POOL_EXECUTOR;

    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, UNIT,
                TASK_QUEUE, THREAD_FACTORY);

        //當設置allowCoreThreadTimeOut(true)時,線程池中"CORE_POOL_SIZE"線程空閒時間達到keepAliveTime也將關閉
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }

    public static Executor getPool() {
        return THREAD_POOL_EXECUTOR;
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章