[Java设计模式](一)怎样实现Singleton(单例)模式编程

单例模式是开发模式中最简单,最易于理解的一种模式。简单地说,它指的就是始终保持一个实例的意思。但是,Java的类是可以穿件多个实例的,那么,怎么实现呢?

顾名思义,单例模式就是只有一个实例。单例模式确保某一个类只有一个实例,这个类称为单例类,单例模式有3个要点:

①是某个类只能有一个实例;

②它必须自行创建这个实例;

③是它必须自行向整个系统提供这个实例。例如,一些资源管理器常常设计成单例模式。

在计算机系统中,需要管理的资源有很多,例如每台计算机可以有若干个打印机,但只能有一个打印控制器,以避免两个打印作业同时输出到打印机中,每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡的情况。

总之,选择单例模式就是为了避免不一致状态。

首先看一个经典的单例模式实现:

public class Singleton {
    private static Singleton uniqueInstance = null;  

    private Singleton() {
       // Exists only to defeat instantiation.
    }  

    public static Singleton getInstance() {
       if (uniqueInstance == null) {
           uniqueInstance = new Singleton();
       }
       return uniqueInstance;
    }
}  

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)

但是以上实现没有考虑线程的安全性,所谓线程安全性,就是如果你的代码所在的进程里有多个线程在同时运行,而这些线程可能同时会运行这段代码,如果每次运行的结果和单线程运行的结果一致,而且他们的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。

Java中实现单例模式一般要注意以下几点:

  • 私有的构造方法,保证外部无法创建类实例。
  • 私有的静态的类型引用。因为静态的就可以保证只有一个变量引用。
  • 提供获取实例的方法。方法名一般为getInstance()。

    单例模式通常有两种实现方式:懒汉式和饿汉式

    1,懒汉式

    对于懒汉式来说,一般需要在getInstance()方法中首先判断实例是否为空,也就是第一次访问的时候才会进入该if语句,然后再返回该实例,例如下面的代码:

private static lanhanObject obj = null;
public static lanhanObject getInstance(){
    if(obj==null)
        obj = new lanhanObject();//创建新的
    return obj;
}

懒汉式有一个缺点,他可能会使线程不安全而无法保证100%的单例,例如,当线程A在以上代码的第4行(进入if语句,创建实例之前)暂停了,此时线程B进入了实例。因此,为了保证懒汉式能做到100%的单例,还需要为getInstance( )方法加上synchronized关键字以保证线程同步,例如如下的代码:

public static synchronized lanhanObject getInstance(){//获取实例方法,保证同步
    if(obj == null){
        obj = new lanhanObject();
        }
    return obj;
}

synchronized 关键字也可以运用在方法体中,用同步代码块的形式来保证线程同步,不一定用同步方法。



2,饿汉式

对于饿汉式来说,需要做就是把new 语句写在引用变量定义的地方,然后getInstance( )直接返回就可以了,例如下面的代码:

private static ehanObject obj = new ehanObject();  //静态的类型引用
public static ehanObject getInstance(){         //获取实例方法
    return obj;
}

饿汉式不存在线程安全的问题,但是他可能会造成资源浪费的情况。因为,实例会在类加载的时候,随着静态变量的初始化而创建,但是有的时候并不会使用该实例,那么它的创建就有一些浪费了,如果实例比较庞大的话,会影响程序的性能。

总之,懒汉式和饿汉式没有绝对的优劣,主要 根据具体的情况来决定。

package com.leetch.java
//饿汉式 单例 优点:实现简单;缺点:在不需要的时候,白创建了对象,造成资源的浪费
class ConnectionPoolA {
    private static ConnectionPoolA cPoolA = new ConnectionPoolA(); // 创建实例
    private  ConnectionPoolA() {}  //私有构造方法
    public static ConnectionPoolA getConnectionPoolA() {
        return cPoolA;
    }

}
//懒汉式 单例 优点:需要对象的时候才创建;缺点:线程不安全
class ConnectionPoolB{
    private static ConnectionPoolB cPoolB;
    private ConnectionPoolB(){}
    public static synchronized ConnectionPoolB getconneConnectionPoolB(){
        if(cPoolB==null){
            cPoolB = new ConnectionPoolB();
        }
        return cPoolB;
    }
}
public class SinglObjectParttern{
    public static void main(String args[]){
        ConnectionPoolA cp = ConnectionPoolA.getConnectionPoolA();  //创建1
        ConnectionPoolB cp2 = ConnectionPoolB.getconneConnectionPoolB();  //创建2
        System.out.println(cp == cp2);
    }
}

因为单例模式下,得到的始终是同一个对象,因此,以上代码的运行结果是 :

true
时间: 2024-10-05 04:58:32

[Java设计模式](一)怎样实现Singleton(单例)模式编程的相关文章

Java设计模式:Singleton(单例)模式

概念定义 Singleton(单例)模式是指在程序运行期间, 某些类只实例化一次,创建一个全局唯一对象.因此,单例类只能有一个实例,且必须自己创建自己的这个唯一实例,并对外提供访问该实例的方式. 单例模式主要是为了避免创建多个实例造成的资源浪费,以及多个实例多次调用容易导致结果出现不一致等问题.例如,一个系统只能有一个窗口管理器或文件系统,一个程序只需要一份全局配置信息. 应用场景 资源共享的情况下,避免由于资源操作时导致的性能或损耗等.如缓存.日志对象.应用配置. 控制资源的情况下,方便资源之

面试题集锦&&实现Singleton(单例)模式-JAVA版

题目:设计一个类,我们只能生产该类的一个实例.(来自<剑指Offer>) 解析:只能生产一个实例的类是实现Singleton(单例)模式的类型.由于设计模式在面向对象程序设计中起着举足轻重的作业,在面试过程中很多公司都喜欢问一些与设计模式相关的问题.在常用的模式中,Singleton是唯一一个能够用短短几十行代码完整实现的模式.因此,写一个Singleton的类型是一个很常见的面试题. 以下我们给出几种解法,供大家参考. *不好的解法一:只适用于单线程环境. 由于要求只能产生一个实例,因此我们

javascript设计模式-singleton(单例)模式

singleton(单例)模式被熟知的原因是因为它限制了类的实例化次数只能一次,单例模式,在该实例不存在的勤快下,可以通过一个方法创建一个类来实现创建类的新实例:如果实例已经存在,则会简单返回该对象的引用.单例模式不同于静态类(或对象),因为我们可以推迟它们的初始化,这通常是因为它需要一些信息,而这些信息在初始化期间可能无法获取,对于没有察觉到之前的引用代码,它们不会提供方便检索方法,这是因为它既不是对象,也不是由一个single返回的类,而是一个结构,在js中,singleton充当共享资源命

Singleton(单例)模式

Singleton(单例)模式用于确保某个类只有一个实例,并且为之提供一个全局访问点. Singleton模式适用情况: 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时 在任何情况下,Singleton模式都建议我们提供能够访问单例对象的公有静态方法.如果使用这个方法创建一个对象,该方法将承担确保仅创建一个实例的责任. Singleton 定义一个Instance操作,允许客户访问它的唯一实例

从别人写的 Object-C 中 Singleton (单例) 模式 中的一些理解--备

关于 面向对象的设计模式 对于面向对象的设计模式,想必大家并不陌生吧. 纵观23种设计模式中,数单例模式(Singleton)和工厂模式(Factory Method)最为熟悉和基础吧.当然,本文总结Singleton模式,对于其他设计模式不做叙说. Singleton模式,即单例模式.顾名思义,主要用于做应用程序的资源共享控制.用途很多?? 实质为,单例是在程序声明周期里 有且仅有 被实例化过一次的类.为确保实例化的唯一,利用类的 类(static)方法来生成和访问对象. 至此,你便可以在程序

C++ Singleton (单例) 模式最优实现

参考:http://blog.yangyubo.com/2009/06/04/best-cpp-singleton-pattern/ 索引 静态化并不是单例 (Singleton) 模式 饿汉模式 懒汉模式 (堆栈-粗糙版) 懒汉模式 (局部静态变量-最佳版) 范例代码和注意事项 (最优实现) 扩展阅读 参考资料 我非常赞成合理的使用 设计模式 能让代码更容易理解和维护, 不过我自己除了简单的 单例 (Singleton) 模式 外, 其它都很少用 :-) 可耻的是, 直到前段时间拜读了 C++

[java]设计模式之singleton(单例)

在日常工作中,有很多对象,我们只需要一个.比如:线程池, 缓存,注册表等.如果制造出多个实例,就会导致许多问题,如程序行为异常,资源使用过量等.这就需要对对象的构建进行控制,使其只能产生一个对象.这就是本篇要讲的设计模式--singleton(单例). 单例模式的定义:确保只有一个类只有一个实例,并提供一个全局访问点. 那么,要如何实现单例模式,使得一个类只能产生一个对象呢?请看下面的实现: public class Singleton { private static Singleton s;

JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖

JAVA之旅(六)--单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖 java也越来越深入了,大家加油吧!咱们一步步来 一.单例设计模式 什么是设计模式? JAVA当中有23种设计模式,解决某一问题最有效的方法 单例设计模式 解决一个类在内存中只存在一个对象 想要保证对象唯一该怎么做> 1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象 2.还为了让其他程序访问到该类对象,只好在本类中自定义一个对象 3.为了方便其他程序对自定义对象的访问,可以对外提供

java设计模式学习 ----- 单例模式(Singleton)

单例模式(Singleton) 单例对象(Singleton)是一种经常使用的设计模式. 在Java应用中,单例对象能保证在一个JVM中,该对象仅仅有一个实例存在.单例模式也分三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有几个长处: 1.某些类创建比較频繁,对于一些大型的对象,这是一笔非常大的系统开销. 2.省去了new操作符,减少了系统内存的使用频率,减轻GC压力. 3.有些类如交易所的核心交易引擎.控制着交易流程,假设该类能够创建多个的话,系统全然乱了.(比方一个军队出现了多个司令员