1 原子性
1.1 java 中的原子操作
1.2 long
和 double
的原子性
1.3 原子操作 + 原子操作 !=
原子操作
2 面试常见问题
2.1 单例模式
2.1.1 饿汉式,静态常量,可用
- 在类装载的时候就完成了实例化,避免了线程同步问题,因为类的加载是由JVM自身保证线程安全的。后续其他类想要调用,永远拿到的都是这个实例。
/**
* @Description 饿汉式,静态常量,可用
* @Author tzb
* @Date 2021/4/11 16:08
* @Version 1.0
**/
public class Singleton1 {
private final static Singleton1 INSTANCE = new Singleton1();
private Singleton1(){
}
public static Singleton1 getInstance(){
return INSTANCE;
}
}
2.1.2 饿汉式,静态代码块,可用
/**
* @Description 饿汉式,静态代码块,可用
* @Author tzb
* @Date 2021/4/11 16:08
* @Version 1.0
**/
public class Singleton2 {
private final static Singleton2 INSTANCE;
static {
INSTANCE = new Singleton2();
}
private Singleton2(){
}
public static Singleton2 getInstance(){
return INSTANCE;
}
}
2.1.3 懒汉式,线程不安全,不可用
- 如果2个线程同时到达19行,由于instance没有被执行过,两个线程都会执行20行。多次创建了实例。
/**
* @Description 懒汉式
* @Author tzb
* @Date 2021/4/11 16:17
* @Version 1.0
**/
public class Singleton3 {
private static Singleton3 instance;
private Singleton3(){
}
public static Singleton3 getInstance(){
if(null == instance){
instance = new Singleton3();
}
return instance;
}
}
2.1.4 懒汉式,线程安全,同步方法,不推荐用
- 效率太低
/**
* @Description 懒汉式,线程安全,不推荐
* @Author tzb
* @Date 2021/4/11 16:17
* @Version 1.0
**/
public class Singleton4 {
private static Singleton4 instance;
private Singleton4(){
}
public synchronized static Singleton4 getInstance(){
if(null == instance){
instance = new Singleton4();
}
return instance;
}
}
2.1.5 懒汉式,线程不安全,同步代码块,不可用
- 2个线程都进入了20行,线程1先执行21,释放锁。线程2后执行21
public class Singleton5 {
private static Singleton5 instance;
private Singleton5(){
}
public static Singleton5 getInstance(){
if(null == instance){
synchronized (Singleton5.class){
instance = new Singleton5();
}
}
return instance;
}
}
2.1.6 双重检测 【推荐,面试用】
- 不加
volatile
,假设进行了重排序,执行了1,2条,左边的rs不为空,但是没有内涵(构造函数没有执行完,里面的属性没有完成赋值)。此时对第2个线程进来,发现rs不为空(但是rs内部没有准备完毕),第2个线程会跳过新建的过程,直接返回,会导致NPE。 - 不加
volatile
,也存在可见性的问题,线程1初始化完了rs,线程2看不到,
/**
* @Description 双重检查
* @Author tzb
* @Date 2021/4/11 16:17
* @Version 1.0
**/
public class Singleton6 {
private volatile static Singleton6 instance;
private Singleton6() {
}
public static Singleton6 getInstance() {
if (null == instance) {
synchronized (Singleton6.class) {
if (null == instance) {
instance = new Singleton6();
}
}
}
return instance;
}
}
2.1.7 静态内部类,推荐用
- 属于懒汉式
/**
* @Description 静态内部类
* @Author tzb
* @Date 2021/4/11 16:17
* @Version 1.0
**/
public class Singleton7 {
private Singleton7() {
}
public static Singleton7 getInstance() {
return SingletonInstance.INSTANCE;
}
private static class SingletonInstance {
private static final Singleton7 INSTANCE = new Singleton7();
}
}
2.1.8 枚举【推荐用】
/**
* @Description 枚举单例
* @Author tzb
* @Date 2021/4/11 16:17
* @Version 1.0
**/
public enum Singleton8 {
INSTANCE;
public void whatever() {
}
}
2.2 不同写法的对比