文章目录
主要是划分两种,饱汉和饿汉。
一、饱汉设计
用的时候再创建(就会有线程安全问题需要处理)
 三步:
- 私有化构造函数
 - 私有化 静态对象
 - 创建 静态获取对象方法
 
public class SingleTon {
    private static SingleTon singleTon;
    private SingleTon(){};
    public static SingleTon getInstance(){
        if (singleTon == null){
            singleTon = new SingleTon();
        }
        return singleTon;
    }
}
 
改进 - 提高线程安全
添加关键字synchronized,加锁
public class SingleTon {
    private static SingleTon singleTon;
    private SingleTon(){};
    public static synchronized SingleTon getInstance(){
        if (singleTon == null){
            singleTon = new SingleTon();
        }
        return singleTon;
    }
}
 
再改进 - 锁的细粒度降低
public class SingleTon {
    private static SingleTon singleTon;
    private SingleTon(){};
    public static SingleTon getInstance(){
        if (singleTon == null){
            synchronized(SingleTon.class){
                singleTon = new SingleTon();
            }
        }
        return singleTon;
    }
}
 
还会有一定的问题,多线程访问的情况下,这个锁不能保证内存中对象唯一。当AB线程同时在第8行后,准备进入第9行,此时A拿到锁进去创建一个对象后释放锁,B还能拿着锁进去创建对象
再再改进 - DCL 双重检查锁定
public class SingleTon {
    private static SingleTon singleTon;
    private SingleTon(){};
    public static SingleTon getInstance(){
        if (singleTon == null){
            synchronized(SingleTon.class){
                if(singleTon == null){
                    singleTon = new SingleTon();
                }
            }
        }
        return singleTon;
    }
}
 
能在多线程情况下,保持高性能。
 但!因为第11行创建对象的操作并不是原子性操作。因此还会有一定的风险
终极改进 volatile 关键字 - 禁止指令重排
因为singleTon= new SingTon()
public class SingleTon {
    private static volatile SingleTon singleTon;
    private SingleTon(){};
    public static SingleTon getInstance(){
        if (singleTon == null){
            synchronized(SingleTon.class){
                if(singleTon == null){
                    singleTon = new SingleTon();
                }
            }
        }
        return singleTon;
    }
}
 
二、饿汉设计
没有线程安全的问题(不管用不用,一直都在内存)
public class SingleTon {
    private static SingleTon singleTon = new SingleTon();
    private SingleTon(){};
    public static SingleTon getInstance(){
        return singleTon;
    }
}
 
三、如何选择
如果对象不大,且创建不复杂,直接用饿汉方式即可
 其他情况则采用懒汉实现方式










