如何创建一个对象(二、单例)

为什么需要单例模式

在应用程序中,经常会用到单例模式,即这个类只能存在一个对象实例。

那么为什么需要这种模式,我们在一个程序应用中,只需要创建一次性的对象实例以节省内存资源,避免重复创建的开销,以便后面使用可以更快的访问。

如何写一个单例模式

  单例作为所有设计模式中最简单的设计模式之一,其创建是非常简单的。

饿汉式单例

#code 饿汉式单例-不推荐
public final class HungrySingleton {

    private byte[] data = new byte[1024];

    private static HungrySingleton instance = new HungrySingleton();

    private HungrySingleton() {
    }

    public static HungrySingleton getInstance() {
        return instance;
    }
}

  以上就是一个典型的饿汉式单例模式,在我们调用HungrySingleton. getInstance()方法时,不仅仅获取了一个已经创建的对象,并且获取了已经初始化了的1k的类变量数据。

即便在多线程环境下,instance也不会被创建两次,因为在类初始化的时候被收集进

懒汉式单例

#code 懒汉式单例-不推荐
public final class LazySingleton {

    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static synchronized LazySingleton getInstance() {
        if (null == instance) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

上面这一段代码其实就是懒汉式单例,我们在真正调用getInstance()方法的时候才去创建这个实例,这个类所需的资源到这个时候才会被开辟。我们同时也使用synchronized来保证多线程环境下只有一份实例。

看起来很美妙,但可惜的是,这个方式也同样不被推荐。原因也很简单,因为我们在使用getInstance()的时候是同步的,意味着每个调用该方法的线程都必须阻塞等待其他线程调用完成,这一点就很耗费性能。

Double Check

#code 双重检查式单例-不推荐
public final class DCSingleton {

    private static volatile DCSingleton instance;

    private DCSingleton() {
    }

    public static DCSingleton getInstance(){
        if (null == instance){
            synchronized (DCSingleton.class){
                if (null == instance){
                    instance = new DCSingleton();
                }
            }
        }
        return instance;
    }
}

在我很长的一段时间内以来,在创建单例实例的时候都喜欢使用这种方式。它既保证了线程安全,也保证了延迟加载,同时相比懒汉式单例的耗费性能,它使用的双重检查的技巧很大程度上缓解了性能浪费,而且volatile修饰的instance也不会被指令重排困扰。看上去很完美,从一定程度上来说的确是这样。

直到我看了doug lea与人合著的那本并发实践书籍,原文是这样的:“DCL这种使用方法已经被广泛的废弃了——促使该模式出现的驱动力不复存在,因而它不是一种高效的优化措施。延迟初始化占位类模式能带来同样的优势,并且更容易理解。”这里的驱动力是指,在新的版本下,无竞争同步的执行速度变快了(以前很慢),JVM的启动速度也变快了(以前很慢)。

延迟初始化占位类模式

#code Holder式单例-推荐max
public final class HolderSingleton {

    private HolderSingleton() {
    }

    private static class Holder {
        private static HolderSingleton instance = new HolderSingleton();
    }

    public static HolderSingleton getInstance() {
        return Holder.instance;
    }
}

从线程安全、高性能、懒加载来看,这个应该是目前最好的单例设计之一,也是使用最为广泛的一个。

枚举式

#code Holder式单例-酌情使用
public enum EnumSingleton {
    INSTANCE;

    EnumSingleton() {
        System.out.println("complete init...");
    }

    public static EnumSingleton getInstance() {
        System.out.println("getInstance...");
        return INSTANCE;
    }

    public static void doneTask() {
        System.out.println("doneTask...");
    }
}

在《Effective Java》那本书中,这个枚举方式实现单例的方式就被极为推荐。枚举方式不允许被继承,同样也只是被实例化一次,但是不能够懒加载。所以读者可以酌情使用。

原文地址:https://www.cnblogs.com/sally-zhou/p/10193292.html

时间: 2024-10-11 08:07:39

如何创建一个对象(二、单例)的相关文章

【黑马】程序员————多线程(二)单例设计模式、线程间通信,JDK1.5互斥锁

------Java培训.Android培训.iOS培训..Net培训.期待与您交流!----- 一.单例设计模式 单例设计模式的意义: A.保证类在内存中只有一个对象,不提供外部访问方式,构造函数用private修饰. B.提供公共方法(static修饰,类的静态方法),获取类的实例.单例设计模式分为饿汉和懒汉两种模式. 饿汉式&懒汉式 class Test33 { public static void main(String[] args) { Fanjianan.getInstance()

PHP设计模式 二 (单例 工厂 注册)

单例模式 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案. 数据库单例示例: <?php namespace Components; class Database { protected static $db; private function __construct(){ //单列模式

MVVM下 利用反射动态创建ViewModel 实现单例

在MVVM一般情况下都会希望ViewModel 在整个应用程序中只有一份实例 传统的做法是用单例模式去实现 : public class ViewModelTest { private ViewModelTest() { } private static ViewModelTest viewModelInstace; public static ViewModelTest GetViewModelTestInstace() { if (viewModelInstace == null) { vi

单例类的创建

#import "SingalTon.h" @implementation SingalTon //实例变量不能在静态方法中使用 //需要定义成全局变量或者静态变量 static  SingalTon * _singleTon=nil; +(SingalTon *) ShareSingleTon { //    返回对象前需要判断,这个对象之前是否创建过,如果没有创建过,就需要创建一个对象,如果创建过,就把上一次创建的对象返回出去 // 多个线程同时访问单例类时,就会创建多个单例类,就

iOS大神班笔记02-模仿苹果创建单例

首先我们得要知道苹果是如何实现单例的:1.不能外界调用alloc,一调用就崩掉,其实就是抛异常(类内部第一次调用alloc就不崩溃,其他都崩溃). 2.提供一个方法给外界获取单例.  3.内部创建一次单例,什么时候创建,程序启动的时候创建单例. 然后我们来创建一个Person类. Person.h #import <Foundation/Foundation.h> @interface Person : NSObject // 获取单例 + (instancetype)sharePerson;

iOS开发——高级篇——iOS中常见的设计模式(MVC/单例/委托/观察者)

关于设计模式这个问题,在网上也找过一些资料,下面是我自己总结的,分享给大家 如果你刚接触设计模式,我们有好消息告诉你!首先,多亏了Cocoa的构建方式,你已经使用了许多的设计模式以及被鼓励的最佳实践. 首先得搞清楚设计模式是个什么鬼,在软件设计领域,设计模式是对通用问题的可复用的解决方案.设计模式是一系列帮你写出更可理解和复用代码的模板,设计模式帮你创建松耦合的代码以便你不需要费多大力就可以改变或者替换代码中的组件 其实iOS中的设计模式有非常多,常用的就下面这四种 一.MVC设计模式(设计模式

黑马程序员_java多线程 单例设计

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- 一.线程的方法 1.yield让出cpu 2.setPriority()设置线程的优先

iOS单例的作用和使用

单例 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 一是某个类只能有一个实例:二是它必须自行创建这个实例:三是它必须自行向整个系统提供这个实例 单例模式的优点: 1.实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例. 2.灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程 在objective-c中要实现一个单例类,至少需要做以下

(一)初识23种设计模式之-----单例设计模式

一  什么是设计模式? 通俗来说,设计模式就是牛人总结的解决某个问题的方案,这套方案被大多数人熟知和认可. 设计模式大致分为三种: 结构型 过滤器模式 组合模式 装饰器模式 外观模式 享元模式,代理模式 创建型    单例模式 工厂模式 抽象工厂模式 建造者模式 原型模式 行为型       责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 空对象模式 策略模式  模板模式 访问者模式 说起设计模式,就不得不说起设计模式的六大设计原则 一  单一职责原则

Spring SingletonBeanRegistry 单例 Bean 注册管理

Spring SingletonBeanRegistry 单例 Bean 注册管理 在 Spring 中 Bean 有单例和多例之分,只有单例的 bean 才会被 BeanFactory 管理,这个工作就是由 SingletonBeanRegistry 完成的. public interface SingletonBeanRegistry { void registerSingleton(String beanName, Object singletonObject); Object getSi