单例模式-Singleton Pattern
单例模式是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点,并隐藏其所有的构造方法。
1.饿汉式单例
类加载的时候就已经初始化了,执行效率高,线程安全,没有任何的锁处理,但是在某些情况会造成内在浪费。
public class Hungrysingleton {
private static Hungrysingleton instance = new Hungrysingleton();
private Hungrysingleton(){}
public Hungrysingleton getInstance()
{
return instance;
}
}
public class HungryStaticSingleton {
private static HungryStaticSingleton instance;
static {
instance = new HungryStaticSingleton();
}
private HungryStaticSingleton(){}
public HungryStaticSingleton getInstance()
{
return instance;
}
}
2.懒汉式单例
方式一:解决了内存的问题,但是线程又是不安全的
public class LazySimpleSingleton {
private static LazySimpleSingleton instance;
private LazySimpleSingleton(){}
public static LazySimpleSingleton getInstance()
{
if(instance == null)
{
instance = new LazySimpleSingleton();
}
return instance;
}
}
方式二:解决线程安全的问题,但是效率又有问题
public class LazySimpleSingleton {
private static LazySimpleSingleton instance;
private LazySimpleSingleton(){}
public synchronized static LazySimpleSingleton getInstance()
{
if(instance == null)
{
instance = new LazySimpleSingleton();
}
return instance;
}
}
方式三:写法优雅,利用了 java 语法的特点,性能高,也避免了内存浪费,会被反射破坏单例
public class LazySimpleSingleton {
private static volatile LazySimpleSingleton instance;
private LazySimpleSingleton(){}
public static LazySimpleSingleton getInstance()
{
if(instance == null)
{
synchronized(LazySimpleSingleton.class)
{
if(instance == null)
{
instance = new LazySimpleSingleton();
}
}
}
return instance;
}
}
3.注册式单例
方式1:枚举式单例,写法优雅,但是也会造成内在浪费
public enum EnumSingleton {
INSTANCE;
public static EnumSingleton getInstance()
{
return INSTANCE;
}
}
方式2:容器式单例,会造成线程不安全的问题,所以需要在操作的加锁
public class ContainerSingleton {
private ContainerSingleton(){}
private static Map<String, Object> ioc = new HashMap<>();
public static Object getInstance(String className)
{
Object instance = null;
if(!ioc.containsKey(className))
{
try
{
instance = Class.forName(className).newInstance();
ioc.put(className, instance);
} catch (Exception err)
{
err.printStackTrace();
}
return instance;
} else
{
return ioc.get(className);
}
}
}
4.TheadLocal单例
保证线程内部的全局唯一,且天生线程安全
public class ThreadLocalSingleton {
private ThreadLocalSingleton(){}
private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance = new ThreadLocal<ThreadLocalSingleton>(){
@Override
protected ThreadLocalSingleton initialValue() {
return new ThreadLocalSingleton();
}
};
public static ThreadLocalSingleton getInstance()
{
return threadLocalInstance.get();
}
}