—-慢慢来比较快,虚心学技术—-

概念

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”

关键点:

某个类只能有一个实例

必须自行创建该实例

必须自行向整个系统提供该实例(提供获取该实例的接口)

其目的是保证类只能有一个实例,对于一些占用资源较大的对象,实例不宜过多,一个够用就行,比如工厂类、资源类

实例

饿汉式单例模式

————声明静态时已经初始化,在类装载时就创建实例

  1. class HungrySingleton{
  2. private static HungrySingleton singleton = new HungrySingleton();
  3. private HungrySingleton(){ //置为private,防止外部实例化
  4. }
  5. public static HungrySingleton getInstance(){
  6. return singleton;
  7. }
  8. }
  9. 。。。。。
  10. HungrySingleton singleton1 = HungrySingleton.getInstance();
  11. HungrySingleton singleton2 = HungrySingleton.getInstance();
  12. System.out.println(singleton1 == singleton2); //结果: true

优点**获取对象的速度较快,且线程安全**(虚拟机保证仅装载一次该类,而在装载类的时候是不会发生并发的)

弊端**:**耗内存

懒汉式单例模式

————-**类装载时不会创建实例,提供一个方法第一次调用时获取实例,往后调用都不会再创建实例**

  1. class LazySingleton{
  2. private volatile static LazySingleton singleton = null; //初始加载不实例化,volatile保证singleton线程安全
  3. private LazySingleton(){ //置为private,防止外部实例化
  4. }
  5. public static synchronized LazySingleton getInstance(){
  6. if (singleton==null){ //首次调用方法时实例化对象
  7. singleton = new LazySingleton();
  8. }
  9. return singleton;
  10. }
  11. }
  12. 。。。。。
  13. LazySingleton lazySingleton1 = LazySingleton.getInstance();
  14. LazySingleton lazySingleton2 = LazySingleton.getInstance();
  15. System.out.println(lazySingleton1 == lazySingleton2); //结果: true

优点**:仅在使用时实例化对象,节约资源

弊端**:如果是在多线程环境下开发,则必须携带synchronized及volatile关键字保证线程安全。而携带了则会影响性能 **

DCL(Double Check Lock)双锁单例模式

———-两次判空检查

  1. class DCLSingleton{
  2. private volatile static DCLSingleton singleton = null; //初始加载不实例化,volatile保证singleton线程安全
  3. private DCLSingleton(){ //置为private,防止外部实例化
  4. }
  5. public static DCLSingleton getInstance(){
  6. if (singleton==null){
  7. synchronized (DCLSingleton.class){
  8. if(singleton==null){
  9. singleton = new DCLSingleton();
  10. }
  11. }
  12. }
  13. return singleton;
  14. }
  15. }
  16. 。。。。。。
  17. DCLSingleton dclSingleton1 = DCLSingleton.getInstance();
  18. DCLSingleton dclSingleton2 = DCLSingleton.getInstance();
  19. System.out.println(dclSingleton1 == dclSingleton2); //结果:true

优点**:线程安全,且初次实例化对象后不会再进行同步锁(synchronized ),资源利用率高

弊端**:首次加载较慢**

应用场景

某类仅要求/允许生成一个对象时

某类的实例化对象需要被共享时(如数据库连接)

某类需要频繁实例化且频繁销毁(如线程池)

如:java的GUI窗口

如有贻误,还请评论指正