- 若是一段代碼是線程安全的,則它不包含競態條件。只有當多個線程更新共享資源時,纔會發生競態條件。
- 棧封閉時,不會在線程之間共享的變量,都是線程安全的。
- 局部對象引用自己不共享,可是引用的對象存儲在共享堆中。若是方法內建立的對象,只是在方法中傳遞,而且不對其餘線程可用,那麼也是線程安全的。
public void someMethod(){
Localobject localobject = new Localobject();
localobject.callMethod();
method2(localobject);
}
public void method2(Localobject localobject{ localobject.setValue("value");
}
複製代碼
不可變對象
html
建立不可變的共享對象來保證對象在線程間共享時不會被修改,從而實現線程安全。 實例被建立,value變量 就不能再被修改,這就是不可變性。java
public class Demo{
private int value = O;
public Demo(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
複製代碼
本質:數據的一致性緩存
- 取 unsafe.getIntVolatile
- 改
- 寫
static{
try{
//反射技術拿到對象
Field theUnsafe = Unsafe.class. getDeclaredField( name: "theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe)theUnsafe.get(null):
//利用unsafe,經過屬性的偏離量(定位到內存中對象內具體的屬性的內存地址)
iOffset = unsafe.objectFieldPffset(LockDemo1.class.getDeclaredField(name: "i")) :
} catch (Exception ex) {
ex.printStackTrace();
}
}
//優化
public void add(){
int current;
//i++;
current = unsafe.getIntVolatile( o: this, iOffset);
unsafe.compareAndSwapInt( o: this.iOffset, current, i1: current + 1):
// CAS命令
}
複製代碼
原理:自旋鎖安全
// volatile int i = 0;
AtomicInteger i = new AtomicInteger(initialValue: 0) ;
public void add() {
i.incrementAndGet():// i++
}
複製代碼
since:JDK 1.8+服務器
- 本文做者:** 留夕
- 本文連接: **www.yuque.com/diamond/ndv…
- 版權聲明: **本博客全部文章除特別聲明外,均採用 CC BY-SA 4.0 許可協議。轉載請註明出處!
- 首發日期: **2019-6-26 22:09:01