volatile变量,用来确保将变量的更新操作通知到其他线程,volatile变量,这个变量是共享的,因此不会将这个变量上的操作与其他内存操作一起重排序。Volatile变量不会被缓存在寄存器,所以,读取volatile时总会返回最新写入的值。但是,volatile的语义不足以确保递增操作的原子性。加锁机制既可以保证可见性由可以确保原子性。volatile只能保证可见性。
当且仅当满足以下条件时,才应该使用volatile:
**1. 对变量的写入操作不依赖变量的当值。
- 该变量不会与其他状态变量一起纳入不变性条件中
- 在访问变量时不需要加锁**
ThreadLocal类:
ThreadLocal对象通常用于防止可变的单实例变量或者全局变量进行共享。
Final 变量:
当满足 这些条件时,对象才是不可变的 - 对象创建以后他的状态就不能改变
- 对象的所有域都是final的
- 对象都是正确创建的(创建期间,this引用没有逸出)
import jdk.nashorn.internal.ir.annotations.Immutable;
import java.util.HashSet;
import java.util.Set;
@Immutable
public final class threeStooes {
private final Set<String> stooes=new HashSet<String>();
public threeStooes(){
stooes.add("23");
stooes.add("ss");
stooes.add("dd");
}
public boolean isStoones(String name){
return stooes.contains(name);
}
}
使用volatile类型发布不可变对象
import java.math.BigInteger;
import java.util.Arrays;
@Immutable
public class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger i, BigInteger[] factors) {
lastNumber = i;
lastFactors = Arrays.copyOf(factors, factors.length);
}
public BigInteger[] getFactors(BigInteger i) {
if (lastNumber == null || !lastNumber.equals(i))
return null;
else return Arrays.copyOf(lastFactors, lastFactors.length);
}
}
线程安全库中的容器类提供了安全发布保证:
以下容器都是安全的:Hashable、synchorizedMap、ConcurrentMap、Vector、CopyOnWriteArrayList、synchorizedList、BlockingQueue、
CopycurrentHashMap也是一个基于散列的Map,但他使用了一种完全不同的加锁策略来提供更高的并发性和伸缩性。CopycurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只能有一个线程访问容器,而是使用一种粒度更细的加锁机制来实现更大程度的共享,这种机制称为—“分段锁”,任意数量的读取线程可以并发的访问Map,执行读取和写入操作的线程 可以并发地访问Map,并且一定数量的写入线程可以并发的修改map。
CopyOnWriteArrayList 用于替代同步list,写时复制(copy-on-write)容器的线程安全性在于,只要正确地发布一个事实不可变得对象,那么在访问该对象时就不在需要进一步的同步。在每一次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。