單例的5中方式
1、懶漢式
缺點(diǎn):線程不安全
/**
* 懶漢式
* 缺點(diǎn):線程不安全的
*/
static class LazyClass {
private static LazyClass lazyClass = null;
private LazyClass (){}
public static LazyClass getInstance(){
if(lazyClass == null) {
lazyClass = new LazyClass();
}
return lazyClass;
}
}
2匀泊、懶漢式變種(雙重檢查加鎖)
/**
* 懶漢式變種
* 注意此處的變量必須加volatile修飾 如果不加volatile可能造成線程不安全
* 主要原因是英文 doubleCheckClass = new DoubleCheckClass() 不是原子操作
* 其中分為三步,第一步開(kāi)辟內(nèi)存空間揣非,第二步初始化對(duì)象躲因, 第三步賦值引用,其中在高并發(fā)場(chǎng)景下可能發(fā)生指重排
* 雙重檢查加鎖
*/
static class DoubleCheckClass {
private static volatile DoubleCheckClass doubleCheckClass = null;
private DoubleCheckClass(){}
public static DoubleCheckClass getInstance(){
if(doubleCheckClass == null) {
synchronized (DoubleCheckClass.class) {
doubleCheckClass = new DoubleCheckClass();
}
}
return doubleCheckClass;
}
}
3搁嗓、餓漢式
/**
*餓漢式
*缺點(diǎn):一上來(lái)就初始化空間,不是用也要占用內(nèi)存空間
*/
static class HungryClass {
private static HungryClasshungryClass= new HungryClass();
private HungryClass(){}
public static HungryClass getInstance(){
returnhungryClass;
}
}
4腺逛、靜態(tài)內(nèi)部類方式
/**
* 靜態(tài)內(nèi)部類方式實(shí)現(xiàn)
*/
static class InnerClass {
private static class InnerClassHolder {
/**
* 靜態(tài)類初始化 JVM來(lái)保證線程安全
*/
private static InnerClass innerClass = new InnerClass();
}
private InnerClass(){}
public static InnerClass getInstance(){
return InnerClassHolder.innerClass;
}
}
5衡怀、枚舉
/**
*枚舉方式實(shí)現(xiàn)單例
*/
static enum EnumClass {
instance;
}
破壞單例的三種方式
1、反射
解決方案:定義一個(gè)全局變量抛杨,當(dāng)?shù)诙蝿?chuàng)建時(shí)候就拋出異常
2、克隆
解決方案:重寫clone方法茁帽,直接返回當(dāng)前單例對(duì)象
3、序列化
解決防范:添加readResolve() 返回單例對(duì)象
/**
* 破壞單例的幾種方式
* 1潘拨、反射
* 2、克隆
* 3季蚂、序列化
*
* 解決方法
* 1琅束、反射
* 定義一個(gè)全局變量扭屁,當(dāng)?shù)诙蝿?chuàng)建的時(shí)候拋出異常
* 2涩禀、克隆
* 重寫clone(),直接返回單例對(duì)象
* 3、序列化
* 添加readResolve(),返回Object對(duì)象
*/
static class Singleton implements Serializable,Cloneable{
private static volatile boolean isCreate = false;//默認(rèn)是第一次創(chuàng)建
/**
* 1.構(gòu)造方法私有化幔欧,外部不能new
*/
private Singleton() {
if(isCreate) {
throw new RuntimeException("已然被實(shí)例化一次丽声,不能在實(shí)例化");
}
isCreate = true;
}
//2.本類內(nèi)部創(chuàng)建對(duì)象實(shí)例
private static volatile Singleton instance;
//3.提供一個(gè)公有的靜態(tài)方法,返回實(shí)例對(duì)象
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return instance;
}
/**
* 防止序列化破環(huán)
* @return
*/
private Object readResolve() {
return instance;
}
}