編寫線程安全需要關心的:
1.共享的變量
2.可變的變量
共享意味著多個線程可以同時訪問,可變意味著其值在生命周期可以改變。
例如以下count 變量:
//線程不安全的類
public class UnsafeCount {
private int count = 0; //該變量是共享的
public void increase() { //這里沒有同步機制,多個線程可以同時訪問
count++; //該變量是可變的
}
public int getCount() {
return count;
}
}
有4種方式可以修復這個問題:
1.不在線程中共享該狀態變量,可以將變量封裝到方法中(無狀態的對象一定是線程安全的);因為方法中變量是每個線程獨占的,不和其它線程共享。比如:
public int add(int count){
return ++count;//這里也可以說無狀態的對象一定是線程安全的
}
2.將狀態變量修改為不可變的變量。
private final int count = 0;
3.在訪問狀態變量使用同步策略。
public synchronized void increase() {
count++;
}
4.使用原子變量類。
private AtomicInteger count;
public void increase() {
count.getAndAdd(1);
}