设计模式学习05----之单例模式

简介: 单例模式,是我们最常用也最熟悉的一种设计模式,其使用要注意线程安全。

单例模式,是我们最常用也最熟悉的一种设计模式,其使用要注意线程安全。


定义

单例模式:顾名思义,就是在应用中有且只有一个实例。一般类似于计数器类的都必须是单例,多例会导致计数结果不准。

一般而言,其分为饿汉式和懒汉式。


懒汉式

懒汉式:顾名思义,就是不在系统加载时创建类的实例。而是在调用时才去一次性创建。

demo如下:

package com.singleton;
/**
 * 懒汉式
 * @author xiang.wei
 */
public class LazySingleton {
  /**
  * 定义一个私有变量,目的是外部不能直接访问该变量,必须通过公共的访问方法来访问
  */
  private static LazySingleton instance=null;
  /**
  * 私有化构造器,使之不能直接构造对象
  */
  private LazySingleton(){
  }
  /**
  * 公共的提取对象的方法
  * @return
  */
  public synchronized static LazySingleton getInstance() {
     if (instance==null) {
             instance=new LazySingleton();
        }
     return instance;
  }
}


饿汉式

饿汉式:与懒汉式相反,饿汉式就是在系统加载时就去创建类的实例。

demo如下:

package com.singleton;
/**
 * 饿汉式
 * @author xiang.wei
 * @create 2018/4/10 10:34
 */
public class HungrySingleton {
    private static final HungrySingleton SINGLETON = new HungrySingleton();
    private HungrySingleton() {
    }
    public static HungrySingleton getInstance() {
        return SINGLETON;
    }
}


总结:饿汉式与懒汉式相比要占用更多的内存,因为系统加载之后就会创建实例。但是效率要比懒汉式要高。


双重加锁

双重加锁是懒汉式的一种扩展。因为直接在getInstance()上加上synchronized会导致每次调用方法时都需要加锁。执行效率不高。所以,我们采用了双重加锁的方式。

package com.singleton;
/**
 * 懒汉式
 * 双重加锁
 * @author xiang.wei
 */
public class LazySingleton_two {
    /**
     * 定义一个私有变量,目的是外部不能直接访问该变量,必须通过公共的访问方法来访问
     */
    private static  volatile LazySingleton_two instance = null;
    /**
     * 私有化构造器,使之不能直接构造对象
     */
    private LazySingleton_two() {
    }
    /**
     * 公共的提取对象的方法
     *
     * @return
     */
    public static LazySingleton_two getInstance() {
        //如果单例存在则直接返回
        if (instance == null) {
            //单例不存在,则进入同步代码块
            synchronized (LazySingleton_two.class) {
                if (instance == null) {
                    System.out.println("实例化的次数");
                    instance = new LazySingleton_two();
                }
            }
        }
        return instance;
    }
}


双重加锁并不是加两个synchronized关键字。

第一个判断是当对象存在时则直接返回实例,当对象不存在时则进入同步代码块中,同步代码块的作用跟之前是相同的,就是防止两个线程同时访问同步代码块的内容,造成生成多个实例的情况。同步代码块每次只允许一个线程进入,创建完实例后返回。第二个判断是当多个线程排队进入代码块时,第一个线程创建完实例返回后,第二个线程再进入时,不需要在创建实例。

采用双重加锁后,代码的执行效率有了较大的提升。


静态内部类的方式

public class MySingleton {
    private static class MySingletonHandle {
        private static final MySingleton instance = new MySingleton();
    }
    private MySingleton() {
    }
    public MySingleton getSingleton() {
        return MySingletonHandle.instance;
    }
}


注:Spring 容器中所有的Bean都是单例的


代码请见:

https://github.com/XWxiaowei/JavaCode/tree/master/design-patterns


参考

https://www.cnblogs.com/V1haoge/p/6510196.html


相关文章
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
29 2
|
14天前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
28 4
|
23天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
6天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
1月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
19 1
|
14天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
23 0
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
25 0
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
本教程详细讲解了Kotlin中的单例模式实现,包括饿汉式、懒汉式、双重检查锁、静态内部类及枚举类等方法,适合需要深入了解Kotlin单例模式的开发者。快速学习者可参考“简洁”系列教程。
33 0
|
2月前
|
设计模式 存储 数据库连接
Python编程中的设计模式之美:单例模式的妙用与实现###
本文将深入浅出地探讨Python编程中的一种重要设计模式——单例模式。通过生动的比喻、清晰的逻辑和实用的代码示例,让读者轻松理解单例模式的核心概念、应用场景及如何在Python中高效实现。无论是初学者还是有经验的开发者,都能从中获得启发,提升对设计模式的理解和应用能力。 ###
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式