第一种:普通饿汉式
package hungry; /** * 单例:饿汉式 * @author lp */ public class HungrySingleton { //在类加载的时候立即初始化,创建单例对象 //优点:没有加任何的锁,执行效率比较高 //用户体验比懒汉式会好一点 //缺点:类加载的时候就初始化,用或者不用都会在占空间 //浪费内存 //绝对线程安全,在线程出现之前就已经实例化了,不存在访问安全问题 private static final HungrySingleton hungrySingleton =new HungrySingleton(); private HungrySingleton(){}; public static HungrySingleton getInstance(){ return hungrySingleton; } }
第二种:静态代码块饿汉式
package hungry;
/**
* 饿汉式的静态单例
* @author lp
*/
public class HungryStaticSingleton {
private static final HungryStaticSingleton hungryStaticSingleton;
static
{
hungryStaticSingleton=new HungryStaticSingleton();
}
private HungryStaticSingleton(){};
public static HungryStaticSingleton getInstance(){
return hungryStaticSingleton;
}
}
第三种:普通懒汉式
package lazy; /** * 懒汉式单例 * @author lp */ public class LazySingleton { //volatile 表示一种轻量级的同步 private volatile static LazySingleton lazySingleton=null; private LazySingleton(){ } /** * * 同步代码块 */ public static LazySingleton getInstance(){ if(lazySingleton==null){ synchronized (LazySingleton.class){ if(lazySingleton==null){ lazySingleton=new LazySingleton(); } } } return lazySingleton; } }
第四种:懒汉式经典
package lazy; /** * 单例模式最经典案例 * @author lp */ public class LazyInnerSingleton { //这种懒汉式避免了饿汉式的内存浪费,也兼顾synchronized性能问题 private LazyInnerSingleton(){ //如果使用的话,先默认初始化内部类,没有使用就不初始化 if(LazyHolder.LAZY!=null){ throw new RuntimeException("创建多个实例错误"); } } //static保证了单例的空间共享 //保证这个方法不会被重写,重载 public static final LazyInnerSingleton getInstance(){ //在返回结果以前,一定会先加载内部类 return LazyHolder.LAZY; } //默认不加载 private static class LazyHolder{ private static final LazyInnerSingleton LAZY=new LazyInnerSingleton(); } } 第五种:注册式单例
package register; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 注册式单例,spring里面就与用这种单例 * @author lp */ public class ContainserSingleton { //空参构造 private ContainserSingleton(){ } //拟合ioc的模式 private static Map<String,Object>ioc=new ConcurrentHashMap<>(); public static Object getInstance(String className){ synchronized (ioc){ if(!ioc.containsKey(className)){ Object object=null; try { object=Class.forName(className).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } ioc.put(className,object); return object; }else{ return ioc.get(className); } } } }
第六种:枚举单例
package register; /** * 枚举单例 * @author lp */ public enum EnumSingleton { //常量中使用,常量就是大家都能够使用。一般定义在api中 INSTANCE; private Object object; public Object getObject(){ return object; } public void setObject(Object object){ this.object=object; } public static EnumSingleton getInstance(){ return INSTANCE; } } 第七种:序列化单例
package seriable; import java.io.Serializable; /** * 序列化单例 * @author lp */ public class SeriableSingleton implements Serializable { //把内存中的状态转化字节码,通过Io流写入到磁盘或者网络的io //反序列化,读取io转化成java对象,转换过程重新new对象 //反序列化的时候对象会被破坏 public static final SeriableSingleton seriableSingleton=new SeriableSingleton(); private SeriableSingleton(){} private static SeriableSingleton getInstance(){ return seriableSingleton; } private Object read(){ return seriableSingleton; } } 第八种:
/** * @author lp */ public class ThreadSingleton { private static final ThreadLocal<ThreadSingleton> threadlocal= new ThreadLocal<ThreadSingleton>(){ protected ThreadSingleton initiValue(){ return new ThreadSingleton (); } }; private ThreadSingleton(){} private static final ThreadSingleton getInstance(){ return threadlocal.get(); } }