介绍:
单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此有些设计大师并把把其称为设计模式之一。
应用:
1、多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
2、Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
3、网站的计数器,一般也是采用单例模式实现,否则难以同步。
4、应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
5、数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
了解了单例模式之后,那么我们就来聊一聊懒汉模式吧!
程序:
1 public class LazySingleton { 2 private static LazySingleton lazySingleton = null; 3 private LazySingleton() { 4 } 5 public static LazySingleton getInstance() { 6 if (lazySingleton == null) { 7 lazySingleton = new LazySingleton(); 8 } 9 return lazySingleton; 10 } 11}
这段代码则为懒汉模式的代码有两个重点
1、先new一个空的对象,用到的时候,再去实例化。
2、构造方法用private修饰,保证只有他自己可以实例化这个对象,别人不能操作。
但是大家有没有看到这段代码其实是有问题的额,单线程操作的时候,当然没有任何问题,但是多线程操作的时候呢?在
getInstance()方法中,假如第一个线程过来,判断lazySingleton==null的时候,lazySingleton确实为空,则往下执行到第7行的时候(停留在第7行,还未执行),第二个线程过来了,
而这个时候,第一个线程还未执行完成new对象操作,则第二个线程判断lazySingleton的时候也为空,则继续往下执行,new出对象,但第一个线程再执行new对象之后,就会把之前的覆盖掉。
那么如何解决呢?
优化:
/** * Created by sww_6 on 2019/4/9. * 注意问题: * 1、在静态方法(static)上添加关键字(synchronized同步锁),就是相当于在类上加锁,锁的范围大,损耗性能。 * 2、加锁、解锁过程消耗资源。 */ public class LazySingleton { private static LazySingleton lazySingleton = null; private LazySingleton() { } public static LazySingleton getInstance() { if (lazySingleton == null) { lazySingleton = new LazySingleton(); } return lazySingleton; } }
好了,懒汉已经到此结束了!