public static Singleton1 getInstanceA () { if ( null == instance) { instance = new Singleton1(); return instance; * 2、适用于多线程环境,但效率不高(不推荐) public static synchronized Singleton1 getInstanceB () { if (instance == null ) { instance = new Singleton1(); return instance; * 3、双重检查加锁(推荐) public static Singleton1 getInstanceC () { // 先判断实例是否存在,若不存在再对类对象进行加锁处理 if (instance == null ) { synchronized (Singleton1.class) { if (instance == null ) { instance = new Singleton1(); return instance;

1、适用于单线程环境(不推荐)

此方式在单线程的时候工作正常,但在多线程的情况下就有问题了。如果两个线程同时运行到判断instance是否为null的if语句,并且instance的确没有被创建时,那么两个线程都会创建一个实例,此时类型Singleton1就不再满足单例模式的要求了。

    public static Singleton1 getInstanceA() {
        if (null == instance) {
            instance = new Singleton1();
        return instance;

2、适用于多线程环境,但效率不高(不推荐)

为了保证在多线程环境下我们还是只能得到该类的一个实例,只需要在getInstanceB()方法加上同步关键字sychronized,就可以了。每次调用getInstanceB()方法时都被synchronized关键字锁住了,会引起线程阻塞,影响程序的性能。

public static synchronized Singleton1 getInstanceB() {
        if (instance == null) {
            instance = new Singleton1();
        return instance;

3、双重检验锁

为了在多线程环境下,不影响程序的性能,不让线程每次调用getInstanceC()方法时都加锁,而只是在实例未被创建时再加锁,在加锁处理里面还需要判断一次实例是否已存在。

    public static Singleton1 getInstanceC() {
        // 先判断实例是否存在,若不存在再对类对象进行加锁处理
        if (instance == null) {
            synchronized (Singleton1.class) {
                if (instance == null) {
                    instance = new Singleton1();
        return instance;

4、静态内部类方式(推荐

加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。 由于在调用 StaticSingleton.getInstance() 的时候,才会对单例进行初始化,而且通过反射,是不能从外部类获取内部类的属性的;由于静态内部类的特性,只有在其被第一次引用的时候才会被加载,所以可以保证其线程安全性。
总结:
优势:兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。
劣势:需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久带的对象。

* Title:StaticSingleton<br> * Description:单例模式——静态内部类方式 * @author QiuChangjin * @date 2018年4月17日 public class StaticSingleton { * 私有构造方法,禁止在其他类中创建实例 private StaticSingleton() { * 获取实例 public static StaticSingleton getInstance() { return StaticSingletonHolder.instance; * 一个私有的静态内部类,用于初始化一个静态final实例 private static class StaticSingletonHolder { private static final StaticSingleton instance = new StaticSingleton(); * 方法A public void methodA() { * 方法B public void methodB() { public static void main(String[] args) { StaticSingleton.getInstance().methodA(); StaticSingleton.getInstance().methodB();

饿汉式单例

1、饿汉式(推荐)

饿汉式单例类:在类初始化时,已经自行实例化。

* Title:Singleton2<br> * Description:单例模式——饿汉式 * @author QiuChangjin * @date 2018年4月17日 public class Singleton2 { private static final Singleton2 instance = new Singleton2(); private Singleton2() { public static Singleton2 getInstance() { return instance;

2、枚举方式(推荐)

创建枚举默认就是线程安全的,所以不需要担心double checked locking,而且还能防止反序列化导致重新创建新的对象。保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量)。

* Title:Singleton<br> * Description:单例模式——枚举方式 * @author QiuChangjin * @date 2018年4月17日 public class Singleton { public static void main(String[] args) { Single single = Single.SINGLE; single.print(); enum Single { SINGLE; private Single() { public void print() { System.out.println("hello world");

就我个人而言,一般情况下直接使用饿汉式就好了,如果明确要求要懒加载(lazy initialization)会倾向于使用静态内部类,如果涉及到反序列化创建对象时会试着使用枚举方式来实现单例。

Java单例模式任何一个系统的大部分配置文件读取、线程安全类工具类、常量类等都会使用单例模式---不要说你没见过,有可能见过但是知道是单例模式,还有你确定你懂单例模式吗?你有梦想吗?哈哈,我想当架构师,我想当CTO,我想当一名技术极客----狗屁!!!先醒一醒,你凭什么能成功,靠嘴皮子,还是靠意淫?单例其实是分成了如下的四种方式 单例—懒汉 单例—饿汗模 *单例—双重检查 单例–基于类初始化
二、如何应用单例设计模 根据定义,一个类只能存在一种对象实例,所以我们需将类的构造访问权限设置成private,只能在类内进行操作。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象, 静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。 三、单例设计 Windows的Task Manager(任务管理器)就是典型的单例模式,你可以唤起任务管理器之后再次打开它,会发现它始终只存在一个 Windows的回收站 网站的计数器应用单例模式,否则难以实现同步 应用程序的日志,因为共享的日志一般一直处于打开状态,如果不以单例模式进行设计难以完成同步追加 数据库的连接池,没有必要实现多个连接池 在Spring中,每个Bean也是单例的,这样做的优点是Spring容器可以管 设计模: 是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索。 共有23种设计模: 创建型模,共5种:工厂方法模、抽象工厂模单例模式、建造者模、原型模。 结构型模,共7种:适配器模、装饰器模、代理模、外观模、桥接模、组合模、享元模。 行为型模,共11种:策略模、模板方法模、观察者模、迭代子模、责任链模、命令模、备忘录模、状态模、访问
单例模式实现主要可以通过饿汉懒汉(DCL)、静态内部类以及枚举实现。 其中饿汉懒汉静态内部类皆可以通过反射或序列化的方式破坏单例,而枚举可以有效的防止反射破坏单例。 注意:单例中的构造是私有的,只有私有构造器才能防止外部类轻易通过构造方法来创建实例,从而破坏单例。 饿汉单例模式 所谓饿汉就是直接在实例初始化时,便调用构造方法来创建单例。 public class Hungry { private Hungry(){ private final static
-------------在面试中,可能会遇到让直接写一个单例模式,不会在意你会不会,理解不理解这东西,只要能写出来,面试就还能进行下去饿汉 class Singleton { private static Singleton instance=new Singleton(); private Singleton(){} static Singleton getInstance() { ​          private static final danli = new Single(); ​          public static Single getInstance(){                   ​ return danli; ​        ...
设计模相关知识在面试中经常被问到,其中的单例模式几乎是每次必问,同时还会要求手写单例模式的代码。至于为什么也不难理解,它的实现代码简短,用较短的时间就能完成,同时代码中也不乏一些细节可以考察面试者的基本功。简单啰嗦一下单例模式的基本知识,借用下网络搜索的结果:       概念上可理解成一个类只有一个实例,实现上是要注意以下三点:       单例模式的类只提供私有的构造函数,
public static LazySingleton getInstance() { if(instance == null) { instance = new LazySingleton(); return instance; 在上面的代码中,私有构造函数确保了只能通过getInstance()方法获取实例。getInstance()方法中,如果没有创建实例,就会创建一个新的实例并返回,否则直接返回已有的实例。 需要注意的是,这种实现方式是线程不安全的,如果多个线程同时调用getInstance()方法,有可能会创建出多个实例。可以通过加来解决线程安全问题,但会导致性能下降,因此通常建议使用饿汉单例模式小太阳〃: 主要是配合mysql的limit的2个参数。 以第一个为例,第1页数据查询:pageSum(页码)为1,pageSize为10,如果不经过计算最终SQL为select * from user limit 1,10,这样是有问题的会漏掉1条。经过计算后(pageSum-1)*pageSize=0,最终SQL为select * from user limit 0, 10,表示从0的位置开始查,一共要查10条。 再比如,点击下一页,第2页数据查询:pageSum(页码)为2,pageSize为10,计算后pageSum=10,pageSize=10,最终SQL为select * from user limit 10, 10,表示从第10的位置开始查,一共要查10条。 Oracle数据泵导入导出(简易版) 技术小白白~: 厉害啊,讲解很仔细,感谢大佬分享,平时不会的可以请教您吗? Java分页算法*3个最常用的 能不能问个小白的问题,1,3的原理是啥?为什么这样可以算得到呢? Java分页算法*3个最常用的 miozus: 如果 idea 排版一下再发出来更好,变量之间都没有空格 - - Oracle创建表空间、创建用户的完整过程 liujianglong: 这篇文章写的真好!