为什么使用单例模式
1.所有使用单例模式的类都没有自己的状态,无论把这个类实例化多少次,实例化多少个对象,结果都是一样的。并且这个类有两个或者两个以上的实例化对象时,会发生程序错误或者与现实逻辑不符的错误。
2.一个类能否做成单例,最容易区分的地方在于,当存在两个或者两个以上的实例化对象时会发生错误。也就是说这个类在整个应用中,同一个时刻只有一种状态。
3.应用实例: 1、一个党只能有一个书记。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
4.优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
1 public class Printer { 2 private static Printer printer =null;//创建一个私有的全局变量 3 /* 4 * 如果有多线程并发访问时,上锁,让其排队等候,一次只能一人用。 5 */ 6 public static synchronized Printer getPrinter(){ 7 if(printer==null){//如果为空,创建本实例 8 printer = new Printer(); 9 } 10 return printer; 11 } 12 /* 13 * 构造私有化,保证在系统的使用中,只有一个实例 14 */ 15 private Printer(){ 16 17 } 18 }
5.如上图的代码上分析,单例模式,首先向外提供了一个可被访问的实例化的对象printer,如果没有此对象时,该Printer类创建一个。如果遇到多线程并发访问,加上关键字Synchronized,上锁让没有持有该对象的类处于等待状态。当前持有该printer的线程任务结束之后,处于等待中的线程才能逐个去持有该实例,去操作其方法。这样的一个过程在编程中被称为单例模式。
如果在系统中不使用单例模式的话,在碰到多线程访问的时候,printer就会给要请求的类,分别在内存中new出一个printer对象,让这些请求的类去做Printer()方法。这样大量占有内存,就会导致系统运行变慢,像电脑的CPU一样,占有量极高,电脑卡死不动的感觉。因为系统的硬件设施需求变动量小,所以只能想出一个节约成本的方法就是单例模式,让多线程处于等待的状态,一个 一个的去解决,这样,即节约内存,提交了运行的成本。也就是单例存在的意义。