1.線程池體系結(jié)構(gòu)
Executor 負(fù)責(zé)線程的使用和調(diào)度的 根接口
|--ExecutorService 接口: 線程池的主要接口。增加了返回Future 對(duì)象
|--ThreadPoolExecutor 線程池的實(shí)現(xiàn)類
|--ScheduledExceutorService 接口: 負(fù)責(zé)線程的調(diào)度
|--ScheduledThreadPoolExecutor : 繼承ThreadPoolExecutor,實(shí)現(xiàn)了ScheduledExecutorService
2.單例模式定義
簡(jiǎn)單理解就是一個(gè)類只能有一個(gè)實(shí)例, 線程池使用中只會(huì)創(chuàng)建一個(gè)實(shí)例
3.餓漢式線程池執(zhí)行工廠
import cn.hutool.core.thread.NamedThreadFactory;
import lombok.NonNull;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 描述:餓漢式 線程池執(zhí)行器工廠.
* 1.單例
* 2.不管有沒(méi)有調(diào)用者都會(huì)提前創(chuàng)建實(shí)例,資源利用效率低
* @author wangkai
*/
public final class HungryThreadPoolFactory {
private HungryThreadPoolFactory() {
}
/**
* 全局訪問(wèn)點(diǎn).
* @param runnable runnable
*/
public static void execute(@NonNull Runnable runnable) {
getInstance().execute(runnable);
}
/**
* 靜態(tài)公用工廠方法,返回唯一實(shí)例.
* @return ThreadPoolExecutor
*/
public static ThreadPoolExecutor getInstance() {
return HungryThreadPoolFactory.THREAD_POOL_EXECUTOR;
}
static final int CPU = Runtime.getRuntime().availableProcessors();
static final int CORE_POOL_SIZE = CPU + 1;
static final int MAXIMUM_POOL_SIZE = CPU * 2 + 1;
static final long KEEP_ALIVE_TIME = 1L;
static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
static final int MAX_QUEUE_NUM = 1024;
/**
* 靜態(tài)私有成員變量.
*/
private static ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
new LinkedBlockingQueue<>(MAX_QUEUE_NUM),
new NamedThreadFactory("ThreadPoolExecutorFactory-", false),
new ThreadPoolExecutor.AbortPolicy());
}
4.懶漢式線程池執(zhí)行工廠
import cn.hutool.core.thread.NamedThreadFactory;
import lombok.NonNull;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 描述:懶漢式 線程池執(zhí)行器工廠.
* 1.單例
* 2.延遲加載:解決了餓漢式不管有沒(méi)有調(diào)用都創(chuàng)建實(shí)例的弊端。但是多線程訪問(wèn)可能會(huì)創(chuàng)建多個(gè)實(shí)例,所以需要解決線程安全問(wèn)題
* @author wangkai
*/
public final class LazyThreadPoolFactory {
private LazyThreadPoolFactory() {
}
/**
* 全局訪問(wèn)點(diǎn).
* @param runnable runnable
*/
public static void execute(@NonNull Runnable runnable) {
getInstance().execute(runnable);
}
/**
* 靜態(tài)私有成員變量.
*/
private static ThreadPoolExecutor THREAD_POOL_EXECUTOR = null;
public static ThreadPoolExecutor getInstance() {
generateInstance();
return LazyThreadPoolFactory.THREAD_POOL_EXECUTOR;
}
static final int CPU = Runtime.getRuntime().availableProcessors();
static final int CORE_POOL_SIZE = CPU + 1;
static final int MAXIMUM_POOL_SIZE = CPU * 2 + 1;
static final long KEEP_ALIVE_TIME = 1L;
static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
static final int MAX_QUEUE_NUM = 1024;
public static void generateInstance() {
//校驗(yàn)實(shí)例是否已生成,避免多線程訪問(wèn)重復(fù)生成實(shí)例
if (THREAD_POOL_EXECUTOR == null) {
THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
new LinkedBlockingQueue<>(MAX_QUEUE_NUM),
new NamedThreadFactory("ThreadPoolExecutorFactory-", false),
new ThreadPoolExecutor.AbortPolicy());
}
}
}
5.靜態(tài)內(nèi)部類實(shí)現(xiàn)線程池工廠(開(kāi)發(fā)中使用的一中方式)
import cn.hutool.core.thread.NamedThreadFactory;
import lombok.NonNull;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 描述:靜態(tài)內(nèi)部類 線程池執(zhí)行器工廠.
* 1.單例
* 2.餓漢式+延遲加載
* @author wangkai
*/
public final class SafeThreadPoolFactory {
private SafeThreadPoolFactory() {
}
/**
* 全局訪問(wèn)點(diǎn).
* @param runnable runnable
*/
public static void execute(@NonNull Runnable runnable) {
ThreadPoolExecutorHolder.THREAD_POOL_EXECUTOR.execute(runnable);
}
/**
* 靜態(tài)內(nèi)部類創(chuàng)建實(shí)例(單例).
* 優(yōu)點(diǎn):被調(diào)用時(shí)才會(huì)創(chuàng)建一次實(shí)例
*/
private static class ThreadPoolExecutorHolder {
static final int CPU = Runtime.getRuntime().availableProcessors();
static final int CORE_POOL_SIZE = CPU + 1;
static final int MAXIMUM_POOL_SIZE = CPU * 2 + 1;
static final long KEEP_ALIVE_TIME = 1L;
static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
static final int MAX_QUEUE_NUM = 1024;
//static變量只會(huì)初始化一次
public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
new LinkedBlockingQueue<>(MAX_QUEUE_NUM),
new NamedThreadFactory("ThreadPoolExecutorFactory-", false),
new ThreadPoolExecutor.AbortPolicy());
}
}