1.定义
Ensure a class has only one instance, and provide a global point of access to it.
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
2.常用代码
private class Singleton{
private static final Singleton singleton = new Singleton();//创建一个不可更改的静态的Singleton对象。
private Singleton(){//私有构造器,外界无法new 出Singleton对象。
}
public static Singleton getInstance(){//获取singleton
return singleton;
}
public void doSometing(){
//逻辑处理
}
}
优点:只有一个实例,减少了内存开支,特别是当一个对象需要频繁地创建,销毁时。
缺点:单例模式没有接口,扩展很困难,对测试也不利。
上面的例子在并发的情况下,会有线程安全的问题出现。解决方法是在获取Singleton对象的方法上加上synchronized。
3.获取固定数量的对象
public class MutilSingleton{
private static Integer maxNum = 2;//指定固定数量
private static ArrayList<MutilSingleton> list = new ArrayList();
//容纳所有的MutilSingleton对象
static{
//初始化list集合
for(int i=0; i<maxNum; i++){
list.add(new MutilSingleton());
}
}
private MutilSingleton(){
}
public static MutilSingleton getInstance(){
//获取随意一个MutilSingleton实例
Random ran = new Random();
Integer index = ran.nextInt(maxNum);
return list.get(index);
}
public void doSomething(){
//逻辑处理
}
}
同样地:该实例在并发情况下会出现线程不安全的问题,解决方法依然是在获取MutilSingleton实例的方法上添加synchronized关键字。
4.工厂模式下的单例模式
// 单例类
public class Singleton{
private Singleton(){
}
}
//工厂类
public class SingletonFacotry{
private static Singleton singleton;
static{//在类加载的时候初始化单例类,只会被加载一次。
try{
Class cls = Class.forName(singleton.getClass().getName()); //获得单例类的类加载器
Constructor con = cls.getDeclaredConstructor();
con.setAccessible(true);
singleton = (Singleton) con.newInstance();
}catch(Exception e){
e.printStackTrace();
}
}
public Singleton getInstance(){//给外部提供获取单例类的方法
return singleton;
}
}