标签:return lis 测试 span for 多个 有一个 vat some
单例模式是一种常见的设计模式,其核心为“每个类只能有一个实例”。通过对类中对象实例化的控制,确保某些场景下状态的唯一性。在系统中的某些类只有一个实例非常重要,如打印任务、一个窗口管理器或文件系统等。
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。例如:系统中可以存在多个打印任务,但只能用一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器;一台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况;一台计算机可以有若干通信端口,但是系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用等。因此,单例模式可以被广泛的应用的下述环境中:
单例模式(Singleton Pattern)即某各类中只有一个实例,且自行实例化并向整个系统提供这个实例。
举例:一个国家只能有一个皇帝(即单例类);
例1: /* 单例模式通用代码*/ package simplePattern; public class Singleton { //定义各一个单例类 private static final Singleton singleton = new Singleton(); //定义私有的构造函数,限制一个类只能产生一个对象 private Singleton(){ } public static Singleton getSingleton(){ return singleton; } //类中其他方法能够其他类调用 public static void doSomething(){ } }
然而,单例模式也存在一些缺点。如:
因此,针对具体情况可以对单例模式进行改进。
例2: public class Singleton_hignconcur { private static Singleton_hignconcur singleton= null; //定义私有的构造函数,限制一个类只能产生一个对象 private Singleton_hignconcur(){ } //方法 public static Singleton_hignconcur getSingleton(){ if(singleton==null){ singleton=new Singleton_hignconcur(); } return singleton; } }
然而,上述代码实现可能存在线程A执行到singleton = new Singleton(),线程B则依然执行到(singleton == null)判断时依然为真,此时,由于A尚未返回实例判断条件仍未null,此时可能出现2个对象,因此线程不安全。
解决上述线程不安全的方法一般有2种,(1)在getSingleton()方法前添加synchronized关键字,或在该方法内添加synchronized关键字,也可使用饿汉式单例(例1)或懒汉式单例模式(例2);(2)考虑对象复制的情况。在JAVA中对象默认不能复制,若实现了Cloneable接口,并实现clone方法,则可以直接通过对象复制方式创建一个新对象,对象复制不需要调用类的构造函数,因此,即使是私有的构造函数,对象仍可被复制。因此,尽量使单例类不实现Cloneable接口。
一个类需要多个对象时,直接使用new关键字即可,只能有一个对象时,使用单例模式,但对于要求某各类只能有n(n可为任一固定自然数)个对象时,如何实现?
public class Emperor { //定义最多能产生的对象数量 private static int maxNum=3; //每个对象(皇帝)拥有的属性(姓名),使用list存储 private static ArrayList<String> nameList = new ArrayList<String>(); //定义一个列表,容纳所有的对象实例 private static ArrayList<Emperor> emperorList= new ArrayList<Emperor>(); //定义当前皇帝的序号 private static int order=0; //产生所有对象 static { for(int i=0;i<maxNum;i++){ emperorList.add(new Emperor("皇帝"+(i+1))); } } private Emperor(){ //存在约束条件(世俗和道德),使得不产生第二个皇帝 } //传入皇帝名称,建立一个对象 private Emperor(String name){ nameList.add(name); } //随机获得一个皇帝实例 public static Emperor getInstance(){ Random ran=new Random(); order= ran.nextInt(maxNum); return emperorList.get(order); } //方法 public static void say(){ System.out.println(nameList.get(order)); } }
public class Minister { public static void main(String[] args){ //定义5个大臣 int maxNum=5; for(int i=0;i<=maxNum;i++){ Emperor emp=Emperor.getInstance(); System.out.println("第"+(i+1)+"个臣子的是:"); emp.say(); } }
}
运行结果如下:
这种需要产生固定数量对象的模式称作有上限的多例模式,是单例模式的一种扩展。采用多例模式可以在设计时觉得在内存中有多少个实例,方便系统进行扩展,修正可能存在的性能问题,提供系统响应速度。
参考《大话设计模式》与《设计模式之禅》
标签:return lis 测试 span for 多个 有一个 vat some
原文地址:https://www.cnblogs.com/mo-lu/p/10274144.html