JMM
java 内存模型,一种约定
VOLATILE
VOLATILE是Java虚拟机提供的轻量级同步机制
***1.保证可见性
//主线程修改了number 子线程不知道一直循坏
static int numnber=0; //加入volatile可解决不可见性
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while (numnber==0){
}
},"a").start();
TimeUnit.SECONDS.sleep(1);
numnber=1;
System.out.println(numnber);
}
2.不保证原子性 如不加=使用lock或者synchronized,还可以使用原子类 如AtomicInteger 保证原子性
3.禁止指令重排***
volatile 在单例模式的应用
private Single() {
//if(single!=null){
// throw new RuntimeException("不要使用反射");
//}
}
private volatile static Single single;
public static Single getInstance() {
if (single == null) {
synchronized (Single.class) {
if (single == null) {
single = new Single();
}
}
}
return single;
}
//使用反射可以破解单例模式
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// Single instance = Single.getInstance();
Constructor<Single> constructor = Single.class.getDeclaredConstructor(null);
constructor.setAccessible(true);
Single instance = constructor.newInstance();
Single instance1 = constructor.newInstance();
System.out.println(instance);
System.out.println(instance1);
}
普通单例模式可以用反射破解 使用枚举可以避免 枚举是用有参构造创建的 底层对反射做了异常处理
unsafe
unsafe类是Java操作C++的一个类
CAS
比较当前工作内存中的值和主内存的值 如果是期望的 则执行操作 否则一直循坏
缺点:1.循环耗时 2. 一次性只能保证一个共享变量的原子性 3.ABA问题
例子:AtomicInteger的自增
原子引用
解决ABA问题 引入原子引用,即乐观锁,