單例模式
單例模式
不要new對象
餓漢式單例,線程安全,浪費資源
public class Hungry {
//浪費空間
private byte[] data1 = new byte[1024*1024];
private byte[] data2 = new byte[1024*1024];
private byte[] data3 = new byte[1024*1024];
private byte[] data4 = new byte[1024*1024];
private Hungry(){
}
private final static Hungry HUNGRY = new Hungry();
public static Hungry getHUNGRY() {
return HUNGRY;
}
}
雙重檢測懶漢式單例。創建實例時,不加同步線程不安全,加了效率不高
public class LazyMan {
private LazyMan(){
System.out.println(Thread.currentThread().getName()+"ok");
}
private volatile static LazyMan lazyMan;
// volatile和if (lazyMan==null)雙重檢測鎖模式的 懶漢式單例 DCL懶漢式
public static LazyMan getLazyMan() {
if (lazyMan==null){
lazyMan =new LazyMan();//不是原子性操作
/*
1.分配內存空間
2.執行構造方法
3.把這個對象指向這個空間
123
可能發生指令重排導致
132 A
B此時lazyMan沒有完成構造
*/
}
return lazyMan;
}
//多線程并發測試
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(()->{
LazyMan.getLazyMan();
}).start();
}
}
}
靜態內部類式
public class OuterClass {
private OuterClass(){
System.out.println(Thread.currentThread().getName()+" ok");
}
public static OuterClass getInstance(){
return InnerClass.OUTER_CLASS;
}
public static class InnerClass{
private static final OuterClass OUTER_CLASS=new OuterClass();
}
}
枚舉類型構造單例
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
public static void main(String[] args) throws Exception{
// EnumSingle enumSingle=EnumSingle.INSTANCE;
Constructor<EnumSingle> declaredConstructor= EnumSingle.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumSingle enumSingle1=declaredConstructor.newInstance();
EnumSingle enumSingle2=declaredConstructor.newInstance();
}
}
破壞單例
使用反射破壞單例
public static void main(String[] args) throws Exception {
// LazyMan lazyMan = LazyMan.getLazyMan();
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan lazyMan1 =declaredConstructor.newInstance();
LazyMan lazyMan2 = declaredConstructor.newInstance();
System.out.println(lazyMan1);
System.out.println(lazyMan2);
}

浙公網安備 33010602011771號