要改進單例模式的實現以確保線程安全并優化性能,有幾種常見的方法。以下是幾種改進 `ThreadUtil` 單例實現的方法:
### 1. 懶漢式(線程安全版)
使用同步機制來確保線程安全,但只在第一次創建實例時同步,這樣既保證了線程安全,又保持了懶加載的特點。
```java
public class ThreadUtil {
? ? private static ThreadUtil instance;
? ? private final ScheduledThreadPoolExecutor mThreadPoolExecutor;
? ? private final ExecutorService singleThreadExecutor;
? ? private ThreadUtil() {
? ? ? ? mThreadPoolExecutor = new ScheduledThreadPoolExecutor(CORE_POOL_SIZE);
? ? ? ? singleThreadExecutor = Executors.newSingleThreadExecutor();
? ? }
? ? public static synchronized ThreadUtil getInstance() {
? ? ? ? if (instance == null) {
? ? ? ? ? ? instance = new ThreadUtil();
? ? ? ? }
? ? ? ? return instance;
? ? }
}
```
### 2. 餓漢式
在類加載時就創建實例,避免了同步問題,但犧牲了懶加載。
```java
public class ThreadUtil {
? ? private static final ThreadUtil instance = new ThreadUtil();
? ? // ... 其他代碼
? ? private ThreadUtil() {
? ? ? ? // ... 初始化代碼
? ? }
? ? public static ThreadUtil getInstance() {
? ? ? ? return instance;
? ? }
}
```
### 3. 雙重檢查鎖定(Double-Checked Locking)
使用雙重檢查鎖定來實現延遲加載和線程安全。
```java
public class ThreadUtil {
? ? private static volatile ThreadUtil instance;
? ? private final ScheduledThreadPoolExecutor mThreadPoolExecutor;
? ? private final ExecutorService singleThreadExecutor;
? ? private ThreadUtil() {
? ? ? ? // ... 初始化代碼
? ? }
? ? public static ThreadUtil getInstance() {
? ? ? ? if (instance == null) {
? ? ? ? ? ? synchronized (ThreadUtil.class) {
? ? ? ? ? ? ? ? if (instance == null) {
? ? ? ? ? ? ? ? ? ? instance = new ThreadUtil();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return instance;
? ? }
}
```
### 4. 靜態內部類
使用靜態內部類的方式來實現單例,這種方式利用了類加載機制來保證初始化實例時的線程安全。
```java
public class ThreadUtil {
? ? private final ScheduledThreadPoolExecutor mThreadPoolExecutor;
? ? private final ExecutorService singleThreadExecutor;
? ? private ThreadUtil() {
? ? ? ? // ... 初始化代碼
? ? }
? ? private static class Holder {
? ? ? ? private static final ThreadUtil INSTANCE = new ThreadUtil();
? ? }
? ? public static ThreadUtil getInstance() {
? ? ? ? return Holder.INSTANCE;
? ? }
}
```
### 5. 枚舉
使用枚舉來實現單例,這是最簡單、最安全的實現方式。
```java
public enum ThreadUtil {
? ? INSTANCE;
? ? private final ScheduledThreadPoolExecutor mThreadPoolExecutor;
? ? private final ExecutorService singleThreadExecutor;
? ? ThreadUtil() {
? ? ? ? // ... 初始化代碼
? ? }
? ? public ScheduledThreadPoolExecutor getThreadPoolExecutor() {
? ? ? ? return mThreadPoolExecutor;
? ? }
? ? public ExecutorService getSingleThreadExecutor() {
? ? ? ? return singleThreadExecutor;
? ? }
}
```
每種方法都有其優缺點,選擇哪一種取決于具體的應用場景和需求。例如,如果單例的實例化成本很高,可能會傾向于使用懶漢式;如果對性能要求極高,可能會選擇靜態內部類或枚舉方式。