最近在看设计模式之禅,书的内容以讲故事的方式介绍了设计模式,强力推荐。
以下是个人对于单例模式的理解
/*
* 单例模式
* 优点:
* 只有一个实例,减少了内存开支,避免对资源的多重占用(写文件方法)
* 只生成一个实例,减少了系统的性能开销
* 可以在系统设置全局的访问点,优化和共享资源访问
* 缺点:
* 没接口,扩展很困难
* 测试不方便
* 注意:
* 高并发情况,单例模式的线程同步问题(建议饿汉式单例)
* 考虑对象的复制情况(建议不要实现Cloneable接口)
*/
public class MyMain {
public static void main(String[] args) {
//Aclass aclass=new Aclass();该句代码会报错,因为Aclass是private的
System.out.println("get方法输出对象:"+Aclass.getA());
Aclass.say();//输出的是同一个实例
Bclass.getB().say();//高并发时,多个线程都是第一次访问方法,可能创建多个实例
//Bclass.say();出现错误,懒汉式单例不应该设计静态方法输出本身实例,因为实例只有在第一次访问get()后才会被创建
for(int i=0;i<10;i++)//循环获取有上限的多例
Cclass.getC().say();
}
}
//核心
//饿汉式单例
class Aclass{
//静态创建自身单例
private static final Aclass a=new Aclass();
//private 限定Aclass的构造函数使Aclass不能被外部创建
private Aclass() {}
//获取Aclass自己创建的单例
public static Aclass getA() {
return a;
}
public static void say() {
System.out.println("这是饿汉式单例,say方法输出对象:"+a);
}
}
//懒汉式单例,添加synchronized保证线程安全
class Bclass{
//静态创建对象
private static Bclass b=null;
//private 限定Bclass的构造函数使Bclass不能被外部创建
private Bclass() {}
//第一次访问时创建并获取Bclass的单例
public static Bclass getB() {
if(b==null)
b=new Bclass();
return b;
}
public void say() {
System.out.println("这是懒汉式单例,say方法输出对象:"+b);
}
}
//扩展
//有上限的多例模式
class Cclass{
//定义类上限个数
private static final int maxCount=3;
//定义一个计数
private static int Count=0;
//定义一个集合容纳本身实例
private static ArrayList<Cclass> cArrayList=new ArrayList<>();
//静态块产生实例并添加到集合里
static {
for(int i=0;i<maxCount;i++)
cArrayList.add(new Cclass());
}
//private 限定Cclass的构造函数使Cclass不能被外部创建
private Cclass() {}
public void say() {
System.out.println("这是多例模式,计数:"+Count+" 对象:"+this);
}
public static Cclass getC() {
if(Count==maxCount)Count=0;
return cArrayList.get(Count++);
}
}