java单利模式设计

java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。

Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。

核心知识点如下:

(1) 将采用单例设计模式的类的构造方法私有化(采用private修饰)。

(2) 在其内部产生该类的实例化对象,并将其封装成private static类型。

(3) 定义一个静态方法返回该类的实例。

/**
 * 方法一
 * 单例模式的实现:饿汉式,线程安全 但效率比较低
 */
public class SingletonTest {  
    // 定义一个私有的构造方法
    private SingletonTest() {
    }  
    // 将自身的实例对象设置为一个属性,并加上Static和final修饰符
    private static final SingletonTest instance = new SingletonTest();  
    // 静态方法返回该类的实例
    public static SingletonTest getInstancei() {
        return instance;
    }  

}

方法一就是传说的中的饿汉模式
优点是:写起来比较简单,而且不存在多线程同步问题,避免了synchronized所造成的性能问题;
缺点是:当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。

/**
 *方法二
 * 单例模式的实现:饱汉式,非线程安全
 *
 */
public class SingletonTest {

// 定义私有构造方法(防止通过 new SingletonTest()去实例化)
    private SingletonTest() {
    }   
    // 定义一个SingletonTest类型的变量(不初始化,注意这里没有使用final关键字)
    private static SingletonTest instance;   
    // 定义一个静态的方法(调用时再初始化SingletonTest,但是多线程访问时,可能造成重复初始化问题)
    public static SingletonTest getInstance() {
        if (instance == null)
            instance = new SingletonTest();
        return instance;
    }
} 

方法二就是传说的中的饱汉模式
优点是:写起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存;
缺点是:并发环境下很可能出现多个SingletonTest实例。

/**
 *方法三
 * 单例模式的实现:饱汉式,线程安全简单实现
 *
 */
public class SingletonTest {
    // 定义私有构造方法(防止通过 new SingletonTest()去实例化)
    private SingletonTest() {
    }   
    // 定义一个SingletonTest类型的变量(不初始化,注意这里没有使用final关键字)
    private static SingletonTest instance;   
    // 定义一个静态的方法(调用时再初始化SingletonTest,使用synchronized 避免多线程访问时,可能造成重的复初始化问题)
    public static synchronized  SingletonTest getInstance() {
        if (instance == null)
            instance = new SingletonTest();
        return instance;
    }
} 

方法三为方法二的简单优化
优点是:使用synchronized关键字避免多线程访问时,出现多个SingletonTest实例。
缺点是:同步方法频繁调用时,效率略低。

/**
 * 方法四
 * 单例模式最优方案
 * 线程安全  并且效率高
 *
 */
public class SingletonTest {

    // 定义一个私有构造方法
    private SingletonTest() {

    }
    //定义一个静态私有变量(不初始化,不使用final关键字,使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用)
    private static volatile SingletonTest instance;  

    //定义一个共有的静态方法,返回该类型实例
    public static SingletonTest getIstance() {
        // 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率)
        if (instance == null) {
            //同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
            synchronized (SingletonTest.class) {
                //未初始化,则初始instance变量
                if (instance == null) {
                    instance = new SingletonTest();
                }
            }
        }
        return instance;
    }
}

方法四为单例模式的最佳实现。内存占用地,效率高,线程安全,多线程操作原子性。

(事实上,可以通过Java反射机制来实例化private类型的构造方法,此时基本上会使所有的Java单例实现失效。本帖不讨论反射情况下问题,默认无反射,也是常见的面试已经应用场景)

时间: 2024-10-06 22:07:38

java单利模式设计的相关文章

java 单利模式设计原理,推荐饿汉式

单例模式的设计: 1 /* 2 这个是先初始化对象. 3 称为:饿汉式. 4 5 Single类一进内存,就已经创建好了对象. 6 class Single 7 { 8 private static Single s = new Single(); 9 private Single(){} 10 public static Single getInstance() 11 { 12 return s; 13 } 14 } 15 */ 16 17 //对象是方法被调用时,才初始化,也叫做对象的延时加

java 单利模式

首先何为单利模式: 单利模式即多次调用同一个对象的时候,只有一个实例(这里所谓的实例就是,假如创建了两个对象,它们的hashCode相同) 下面是相关代码: 1 创建一个对象Singleton类 package Singleton; public class Singleton { } 2 我们进行测试: package Singleton; public class SingletonTest { public static void main(String[] args) { Singlet

Java设计模式-单利模式

单例模式 作为对象的创建模式,单例模式确保其某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类.单例模式有以下特点: 1.单例类只能有一个实例 2.单例类必须自己创建自己的唯一实例 3.单例类必须给其他所有对象提供这一实例 下面看一下单例模式的三种写法,除了这三种写法,静态内部类的方式.静态代码块的方式.enum枚举的方式也都可以,不过异曲同工,这三种方式就不写了. 首先声明就是 在我们项目工程中 我们完全不用使用懒汉式 因为有锁使用的地方就有效率低的存在: 饿汉式

Java设计模式の单利模式

单利模式:确保一个类最多只有一个实例,并提供一个全局访问点. 经典单利模式创建对象代码 public class Singleton { private static Singleton uniqueInstance = null; private Singleton(){ } public static Singleton getInstance(){ if (uniqueInstance==null) { uniqueInstance=new Singleton(); } return un

单利模式的优缺点和使用场景

文章转自:http://www.tools138.com/create/article/20150929/020009847.html 首先介绍一下单例模式:     单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这

模式设计 - 单例模式

一个类能返回对象的一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名 称). 使用需要注意: 使用注意事项:     1.使用时不能用反射模式创建单例,否则会实例化一个新的对象     2.使用懒单例模式时注意线程安全问题.在多线程环境下要注意,如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例, 这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则. 解决这个问题的办

《JAVA与模式》之原型模式

在阎宏博士的<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象.这就是选型模式的用意. 原型模式的结构 原型模式要求对象实现一个可以"克隆"自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例.这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新

《JAVA与模式》之工厂方法模式

在阎宏博士的<JAVA与模式>一书中开头是这样描述工厂方法模式的: 工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式. 工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中. 那么工厂方法模式是在什么场景下使用呢,下面就以本人的理解举例说明: 相信很多人都做过导入导出功能,就拿导出功能来说.有这么一个需求:XX系统需要支持对数据库中的员工薪资进行导出,并且支持多种格式

《JAVA与模式》之适配器模式

在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的用途 用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极.阴极外,还有一个地极.而有些地方的电源插座却只有两极,没有地极.电源插座与笔记本电脑的电源插头不匹配使得笔记本电脑无法使用.这时候一个三相到两相的转换器(适配器)就能解决此问题,而这正像是本模式所做的事情. 适配器模式