? ? ? 主要有下面三個加在類上的線程安全相關的注解。
一.@Immutable
? ? ? ? 標記一個類為不可變的。這意味著該類的實例在構造完成后,其狀態(數據)永遠不能被更改。實現不可變性的嚴格條件(Java內存模型中的定義):
所有字段都是?
final
?的:這確保了在構造函數執行完畢后,所有字段的引用對其他線程是可見的(通過?final
?的語義保障),并且引用不能再指向其他對象。類本身被聲明為?
final
:防止子類覆蓋其方法并意外地改變狀態(“破壞性繼承”)。this
?引用沒有逸出:在構造函數執行期間,this
?引用不能提供給其他代碼,防止其他代碼在對象完全構造之前就看到它。對可變狀態的正確管理:
如果類包含對可變對象的引用(例如,一個?final List<String>
),那么必須:
- 如果需要返回內部可變狀態,返回其防御性拷貝,而不是原始引用。
- 不要提供任何可以修改這些可變狀態的方法(如setter)。
- 在構造函數中,深度拷貝任何傳入的可變參數,而不是直接存儲其引用。
下面是注解源碼:
? ? ? ?可以發現有兩個地方存在@Immutable注解,它們的來源不一樣,我們應該使用第一個并發包下的注解。第二個不太穩定。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package javax.annotation.concurrent;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Immutable {
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package jdk.nashorn.internal.ir.annotations;public @interface Immutable {
}
總結
javax.annotation.concurrent.Immutable
:是公共的、受支持的、有用的并發編程工具注解,用于文檔化和靜態分析。jdk.nashorn.internal.ir.annotations.Immutable
:是內部的、已廢棄的、特化的JDK實現細節注解,與應用程序開發無關。
二.@ThreadSafe
? ? ? ?標記一個類是線程安全的。這意味著該類的實例可以在多線程環境下被安全地并發使用,其內部方法會維護狀態的一致性。
實現方式(多種途徑):
無狀態:類沒有任何字段,自然是線程安全的。(如:只包含靜態工具方法的類)。
使用不可變狀態:即類本身是?
@Immutable
?的。使用內置鎖 (
synchronized
):通過同步方法或同步代碼塊來保護所有訪問狀態的臨界區。使用并發容器:例如,使用?
ConcurrentHashMap
?代替?HashMap
,使用?AtomicInteger
?代替?int
。使用顯式鎖 (
java.util.concurrent.locks.Lock
):提供更靈活的鎖定機制。
? ? ? ?下面是concurrent包下的
注解源碼。(其實java中還有別的@ThreadSafe注解,問題與上面一個注解類似,有不同的來源,主要使用下面這個)
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package javax.annotation.concurrent;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface ThreadSafe {
}
三.@NotThreadSafe
? ? ? ?明確標記一個類是非線程安全的。這意味著該類的實例不能在多線程間共享,除非由調用者通過外部手段(如外部同步)來協調訪問。
為什么需要它?
默認情況:Java中的大多數類(如?
ArrayList
,?HashMap
,?StringBuilder
)默認都是非線程安全的,以實現最佳性能。明確警示:加上此注解是一個非常好的實踐,它明確地告訴使用者:“注意!這個類不是線程安全的,你不能直接在多線程環境下使用它”,避免了潛在的誤用和難以發現的并發Bug。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package javax.annotation.concurrent;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface NotThreadSafe {
}