10.底层原理之原子性

1.简介
一系列的操作,要么全部执行成功,要么全部不执行,不会出现执行一半的情况,是不可分割的,这种特性被称之为原子性。

2.Java中的原子操作

private int count = 0;
public void calculate(){
	count++;
}
  1. 将count从主存中读取到线程的工作内存
  2. 处理器执行++操作
  3. 将处理器执行的结果写到工作内存
  4. 将线程工作内存计算的值flush到主存中

3.注意事项

  • java.concurrent.Atomic.*包中所有类都具有原子性
  • i++不具有原子性,但可以用synchronized关键字来实现原子性
  • 原子操作 + 原子操作 != 原子操作

4.单例模式
(1).为什么使用单例模式?
当需要控制实例数目,节省系统资源的时候可以使用单例模式。保证一个类仅有一个实例,并提供一个访问它的全局访问点,这样可避免一个全局使用的类频繁地创建与销毁。

(2).使用场景

  • 无状态的工具类,如日志工具类,不管是在哪里使用,只是使用它来记录日志信息,并不需要在它的实例对象上存储任何状态,此时,只需要一个实例对象即可。
  • 全局信息类,如在一个类上记录网站的访问次数,但并不希望访问有的被记录在对象A上,有的被记录在B上,这时也可以让这个类成为单例。

(3).饿汉式(静态常量)(可用)

public class Singleton {
    private final static Singleton instance = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return instance;
    }
}

(4).饿汉式(静态代码块)(可用)

public class Singleton {
    private final static Singleton instance;

	static {
		instance = new Singleton();
	}
	
    private Singleton() {

    }

    public static Singleton getInstance() {
        return instance;
    }
}

(5).懒汉式(线程不安全)(不可用)

public class Singleton {
    private static Singleton instance;
	
    private Singleton() {

    }

    public static Singleton getInstance() {
    	//存在多个线程竞争的情况
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

(6).懒汉式(线程安全但不推荐,效率低)(可用)

public class Singleton {
    private static Singleton instance;
	
    private Singleton() {

    }

    public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

(7).懒汉式(线程不安全)(不可用)

public class Singleton {
    private static Singleton instance;
	
    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
        	//两个线程都进入的话,会导致创建两个实例的问题
            synchronized (Singleton.class) {
                instance = new Singleton();
            }
        }
        return instance;
    }
}

(8).双重检查(推荐)

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

为什么使用双重检查?
1.保障线程安全
2.弥补懒汉式线程安全但效率低的缺陷

为什么使用volatile?
1.新建对象实际上有3个步骤,创建一个空对象,调用构造函数初始化,将实例传给对象引用
2.重排序会带来空指针异常,需要防止重排序

(9).静态内部类(懒汉式))(可用)

public class Singleton {
    private Singleton() {
    }

    private static class SingletonInstance {

        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

(10).枚举单例(可用)

public enum Singleton {
    INSTANCE;

    public void whatever() {

    }
}

(11).单例模式总结
饿汉:简单,但是没有懒加载
懒汉:存在线程安全问题
静态内部类:可用
双重检查:面试用
枚举类:生产中推荐使用

  • 写法简单
  • 线程安全,枚举经过反编译,本质是静态的对象
  • 可以防止反序列化破坏单例,重新创建新的对象
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值