单例模式下的类仅有一个对象,且由自身进行创建与管理,与其类似的设计模式还有多例模式,多例模式由自身创建并管理多个对象
一.饥饿式单例模式
class Single{
//饥饿式
private static final Single instance = new Single();
private Single(){}
public static Single getInstance(){
return instance;
}
}
二.注册式单例模式
class SingleRegister{
//注册式
static private HashMap<String,Object> reg = new HashMap<>();
//静态代码段仅在对象初始化时执行一次,且仅能初始化静态变量
static {
reg.put("SingleRegister",new SingleRegister());
}
private SingleRegister(){}
public static SingleRegister getInstance(String name){
try {
if (reg.get(name) == null) {
reg.put(name, Class.forName(name).newInstance());
}
}catch (Exception e){
e.printStackTrace();
return null;
}
return (SingleRegister) (reg.get(name));
}
}
三.延迟式单例模式
class SingleLazy{
//延迟式
private SingleLazy(){}
private static SingleLazy instance = null;
public static SingleLazy getInstance(){
if(instance == null)
instance = new SingleLazy();
return instance;
}
}
四.多线程安全延迟式单例模式
1.双重检查锁
class SingleLazyThread{
//多线程版延迟式
private SingleLazyThread(){}
private volatile static SingleLazyThread instance;
//加了volatile则若一个线程对变量进行了更改则通知其余线程重新进入内存读取
//数据,而不是读取cache内的值
public static SingleLazyThread getInstance(){
//双重检查锁
if(instance == null){
synchronized (SingleLazyThread.class){
if(instance == null){
instance = new SingleLazyThread();
}
}
}
return instance;
}
}
2.静态内部类
class SingleLazyThreadByStatic{
//静态内部类实现lazy单例模式的线程安全
private static class InstanceHolder{
public static final SingleLazyThreadByStatic instance = new SingleLazyThreadByStatic();
}
//实现原理:
//外部类在加载时不会加载内部类,因此实现了lazy
//且虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确地加锁、同步,从而保证了线程安全
public static SingleLazyThreadByStatic getInstance(){
return InstanceHolder.instance;
}
private SingleLazyThreadByStatic(){}
}
五.多例模式
class Multi{
//多例模式
static private Multi multi = new Multi();
static private Multi multi1 = new Multi();
private Multi(){}
static private List<Multi> list = new ArrayList<>();
static{
list.add(multi);
list.add(multi1);
}
public static Multi getInstance(int index){
//指定拿哪一个instance
return list.get(index);
}
}
Comment