设计模式之单例模式Singleton(三创建型)

 1.什么事单例模式?

  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

  单例模式有以下特点:
    1、单例类只能有一个实例。
    2、单例类必须自己创建自己的唯一实例。
    3、单例类必须给所有其他对象提供这一实例。

  单例模式主要分为:饿汉模式,懒汉模式。

  饿汉式和懒汉式区别:

  从名字上来说,饿汉和懒汉,饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。

  单例模式着重涉及到了一个线程安全性的问题。

  什么是线程安全?

  如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

  或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。

 2.单例模式应用场景

1. Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~

2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

3. 网站的计数器,一般也是采用单例模式实现,否则难以同步。

4. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

5. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

6. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。

7. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

8. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统

3.单例应用举例。

主要实现与解释都写在了代码之中。

/**
* @FileName Singleton.java
* @Package com.ali.pattern.singleton
* @Description
* <p>这里稍微对这里涉及到的几个关键字做一下介绍:
* 一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,
* 因此不能将它cache在线程memory中。volatile是变量修饰符,
* 而synchronized则作用于一段代码或方法。
* volatile只是在线程内存和“主”内存间同步某个变量的值,
* 而synchronized通过锁定和解锁某个监视器同步所有变量的值。
* 显然synchronized要比volatile消耗更多资源。
* 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
        final类不能被继承,没有子类,final类中的方法默认是final的。
        final方法不能被子类的方法覆盖,但可以被继承。
        final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
        final不能用于修饰构造方法。
        注意:父类的private成员方法是不能被子类方法覆盖的,
        因此private类型的方法默认是final类型的。
   static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,
        也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
        被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,
        它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,
   Java虚拟机就能根据类名在运行时数据区的方法区内找到他们。
        因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
        用public修饰的static成员变量和成员方法本质是全局变量和全局方法,
        当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。 </p>
* @Author ali blog:http://www.cnblogs.com/accipiter
* @Date 2016年1月19日下午1:21:46
* @Version V1.0.1
*/
package com.ali.pattern.singleton;

/**
 * @ClassName Singleton
 * <p>但是以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的</p>
 * @Description TODO
 * @Date 下午1:21:46
 */
public class Singleton {
    //饿汉
    private static Singleton sigleton1 = new Singleton();
    /**
    * @Title getInstanceE
    * @Description 饿汉模式,本身就是线程安全的。
    * @return
    * @Return Singleton
    * @Throws
    * @user Administrator
    * @Date 2016年1月19日
     */
    public static Singleton getInstanceE(){
        return sigleton1;
    }
    //懒汉
    private static Singleton singleton=null;
    private Singleton()    {
    }
    /**
    * @Title getInstance
    * @Description 线程不安全
    * @return
    * @Return Singleton
    * @Throws
    * @user Administrator
    * @Date 2016年1月19日
     */
    public static Singleton getInstance(){
        if(null==singleton){
            singleton=new Singleton();
        }
        return singleton;
    }
    /**
    * @Title getInstanceSafe
    * @Description 线程安全,每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,
    * @return
    * @Return Singleton
    * @Throws
    * @user Administrator
    * @Date 2016年1月19日
     */
    public static synchronized Singleton getInstanceSafe(){
        if(null==singleton){
            singleton=new Singleton();
        }
        return singleton;
    }
    /**
    * @Title getInstanceSafeD
    * @Description 双重锁定
    * 确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,
    * 同时避免了每次都同步的性能损耗
    *
    * @return
    * @Return Singleton
    * @Throws
    * @user Administrator
    * @Date 2016年1月19日
     */
    public static Singleton getInstanceSafeD(){
        if(null==singleton){
            synchronized (Singleton.class) {
                if(null==singleton){
                    singleton=new Singleton();
                    }
                }
            }
        return singleton;
    }
    /**
    * @ClassName LazyHolder
    * @Description 静态内部类,既实现了线程安全,又避免了同步带来的性能影响
    * @Date 下午1:44:53
     */
    private static class LazyHolder{
        private static final Singleton singleton=new Singleton();
    }
    public static final Singleton getInstanceClass(){
        return LazyHolder.singleton;
    }

    public void operate(int i){
        System.out.println(i+"、操作!");
    }
    /**
     * @Title main
     * @Description TODO
     * @param args
     * @Return void
     * @Throws
     * @user Administrator
     * @Date 2016年1月19日
     */
    public static void main(String[] args) {
        Singleton.getInstance().operate(1);
        Singleton.getInstanceSafe().operate(2);
        Singleton.getInstanceSafeD().operate(3);
        Singleton.getInstanceClass().operate(4);
        Singleton.getInstanceE().operate(5);
    }

}
时间: 2024-10-18 22:45:40

设计模式之单例模式Singleton(三创建型)的相关文章

C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)

一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配. 从范围来看: 类模式处理类与子类的静态关系. 对象模式处理对象间的动态关系. 二:Singleton (创建型模式) 单件 1.动机(Motivation) 软件系统中,经常有这样一些特殊的类,必须保证他们在系统中只存在一个实例,才能确保它们的逻辑正确性,以及良好的效率. 如何绕过常规的构造器,

设计模式(二)单例模式Singleton(创建型)

几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销.再如大家最经常用的IM,如QQ,在同一台电脑,一个帐号只能有唯一的登录. 1. 问题 怎样确保一个特殊类的实例是独一无二的(它是这个类的唯一实例),并且这个实例易于被访问呢? 2. 解决方案 1)全局变量:一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象.因为你的任何代码都能修改全局变量,这将不可避免的引起

设计模式(四) : 创建型模式--单例模式

单例模式的话,类图上来看是最简单的设计模式,就是一个类只能有一个自己的实例. 单例模式通常来说我们就有Lazy loading的和不是Lazy loading的.<java与模式>里面的关于这两种的类图,: 可以看到一个是现开始就实例话的,这样的话不符合我们的lazy loading,还有一种是在getinstance方法里头去new的,这样的话会有线程安全的问题,我们提供了双重检查锁. 下面看示意代碼︰ 1. 静态初始化: package com.javadesignpattern.Sing

23种设计模式介绍(一)---- 创建型模式

由于设计模式篇幅比较大,如果在一篇文章讲完所有的设计模式的话不利于阅读.于是我把它分为三篇文章 23种设计模式介绍(一)---- 创建型模式 23种设计模式介绍(二)---- 结构型模式 23种设计模式介绍(三)---- 行为型模式 由于设计模式都是比较抽象的概念,所以大家一定要确保看懂类图,而后再自己写代码加强记忆. 简介 设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接

php设计模式(一):简介及创建型模式

我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式. 一.设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用.容易被他人理解的.可靠的代码设计经验的总结. 设计模式不是Java的专利,我们用面向对象的方法在PHP里也能很好的使用23种设计模式. 那么我们常说的架构.框架和设计模式有什么关系呢? 架构是一套体系结构,是项目的整体解决方案:框架是可供复用的半成品软件,是具体程序代码.架构一般会涉及到采用什么样的框架来加速和优化某部分问题的解决,而好的框架代

设计模式之单例模式——Singleton

                    设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有公开的调用方法.而且,别的类不能实例化它,所以构造方法要设置为私有的. 单例模式的要点 一是某个类只能有一个实例: 二是它必须自行创建这个实例: 三是它必须自行向整个系统提供这个实例. 例如: 有一个"单例对象",而"客户甲"."客户乙" 和&quo

java设计模式之单例模式(Singleton)

Java设计模式之单例模式 单例模式是什么? 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式如何来设计呢? 保证一个类只能有一个实例,那么我们不能无限制的new 来创建,因为我们知道,new一次就是一个新的对象,那么构造器只能私有化private -- 构造器私有化 构造器私有化了,问题又出现了,构造器私有化了,那么我们怎么来创建唯一的对象呢?-- 提供一个公有的方法/提供一个公有的静态属性 再分析一下,公有方法, 实例方法还是类方法呢?--公有的类方法(获取类实例) 依据以上

设计模式(五) : 创建型模式--建造者模式

建造者模式的意图是将产品的内部表象和产品的生产过程分割开来. 类图: 示意性代码: package com.javadesignpattern.builder; public interface Builder { public void buildPart1(); public void buildPart2(); public Product retrieveProduct(); } ? 1 2 3 4 5 6 7 package com.javadesignpattern.builder;

设计模式-04 建造者模式(创建型模式)

一 建造者模式 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 主要解决:在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定. 关键代码 : 建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系. 使用场景: 汽车有很多部件,车轮

设计模式(二)单件模式Singleton(创建型)

SINGLETON(单件)—对象创建型模式 几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销.再如大家最经常用的IM,如QQ,在同一台电脑,一个帐号只能有唯一的登录. 1. 问题 怎样确保一个特殊类的实例是独一无二的(它是这个类的唯一实例),并且这个实例易于被访问呢? 2. 解决方案 1)全局变量:一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象.因为你的