饿汉式单例
package com.zhang.singletest;
/**
* 饿汉式单例
*/
public class HugryTest {
//私有构造
private HugryTest(){};
private final static HugryTest hugryTest = new HugryTest();
public HugryTest getInstance(){
return hugryTest;
}
}
懒汉式单例
package com.zhang.singletest;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 懒汉式单例
*/
public class LazyManTest {
//私有构造
private LazyManTest(){
System.out.println(Thread.currentThread().getName()+"");
//可以在这里做些判断防止构造破坏单例 ,但是无论怎样都没办法百分百保证安全 枚举才是最安全的单例(会抛出异常)
}
private volatile static LazyManTest lazyManTest =null; //保证可见性和禁止指令重排
//双重验证
public static LazyManTest getInstance(){
if(lazyManTest==null){
synchronized (LazyManTest.class){
if(lazyManTest==null){
lazyManTest = new LazyManTest();
}
}
}
return lazyManTest;
}
public static void main(String[] args) throws NoSuchMethodException {
//多线程使用单例
/*ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
executorService.execute( () ->{
System.out.println(Thread.currentThread().getName()+"获取唯一单例===>"+LazyManTest.getInstance());
});
}
executorService.shutdown();
*/
//使用反射破解单例
Class<LazyManTest> lazyManTestClass = LazyManTest.class;
Constructor<LazyManTest> constructor = lazyManTestClass.getDeclaredConstructor(null);
constructor.setAccessible(true); //强制私有无效
LazyManTest lazyManTest = null;
try {
lazyManTest = constructor.newInstance(null);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(lazyManTest);
System.out.println(LazyManTest.getInstance());
}
}
枚举
package com.zhang.singletest;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public enum EnumSingleTest {
INSTANCE;
public static EnumSingleTest getInstance(){
return INSTANCE;
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//试图用反射破坏枚举
Class<EnumSingleTest> singleTestClass = EnumSingleTest.class;
Constructor<EnumSingleTest> declaredConstructor = singleTestClass.getDeclaredConstructor(String.class, int.class);
declaredConstructor.setAccessible(true);
declaredConstructor.newInstance("", 1);
}
}
执行报错
Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at com.zhang.singletest.EnumSingleTest.main(EnumSingleTest.java:20)