单例模式

GCD之用dispatch_once创建单例

给你一囗甜甜゛ 提交于 2020-03-03 21:25:34
单例模式是开发者常用的一种设置模式,常见的实现方式为:在类中编写名为 sharedInstance的方法,该方法只会返回全类共用的单例实例,而不会在每次调用时创建新的实例. 常见的做法是: + (instancetype)sharedUser { static User *_sharedInstance = nil; @synchronized(self) { if (!_sharedInstance) { _sharedInstance = [[self alloc] init]; } } return _sharedInstance; } 为了保证线程安全,上面的代码把创建代理的代码包裹在同步块里. 相对于上面的实现方式,使用GCD的dispatch_once实现起来更为容易. 所用到的函数是: static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // code to be executed once }); 此函数接受的类型为 dispatch_once_t的特殊函数 token,此外还接受块参数.对于给定的token来说,该函数保证相关的块必定会执行,且仅执行一次.首次调用该函数时必然会执行块中的代码, 最重要的是:次操作完全是线程安全的!!!需要注意的是:对于只需执行一次的块来说

Java设计模式之单例模式

半城伤御伤魂 提交于 2020-03-03 17:33:03
单件模式(Singleton Pattern) :用来创建独一无二的,只能有一个实例的对象的入场券。 单件模式的作用: 有一些对象其实我们只需要一个,如线程池(threadpool),缓存(cache),对话框,处理偏好设置和注册表(registry)的对象,日志对象,充当打印机,显卡等设备驱动程序的对象。事实上,这些类对象只能有一个实例,如果制造出多个实例,就会导致许多问题产生。如程序的行为异常,资源使用过量,或者是不一致的结果。 或许我们可以利用全局变量来做到,但是如果将对象赋值给一个全局变量,那么必须在程序一开始就创建好对象(这其实和实现有关,有些jvm的实现是:在用到的时候才创建对象。),万一这个对象非常耗费资源,而程序在这次的执行过程中又一直没用到它,着就会造成资源的浪费。利用单件模式,我们可以在需要时才创建对象。 剖析经典的单件模式实现 public class Singleton { //利用一个静态变量来记录Singleton类的唯一实例 private static Singleton uniqueInstance; //把构造器声明为私有的,只有自Singleton类内才可以调用构造器 private Singleton() {} //用getInstance()方法实例化对象,并返回这个实例 public static Singleton

设计模式实战——开发中常用到的单例模式

假如想象 提交于 2020-03-02 17:45:32
本系列博客是自己在学习设计模式过程中收集整理的文章集合,其他文章参看 设计模式传送门 单例模式简介 单例模式的目的是保证系统中只有类的一个实例对象,并且提供一个全局的入口点来获取并使用这个实例对象。 使用单例模式可以防止用户“胡乱”创建对象,耗费内存。而且有些对象从逻辑上来讲一个系统中只应该存在一个,比如说 Runtime 类,使用单例模式也能很好的保证这一点。 本文介绍几个我们平时开发过程中常用到的单例模式场景,来加深我们对单例模式的理解。 JDK中的单例模式 Runtime 类封装了Java运行时的环境。每一个java程序实际上都是启动了一个JVM进程,那么每个JVM进程都是对应这一个Runtime实例,此实例是由JVM为其实例化的。每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。 由于Java是单进程的,所以,在一个JVM中,Runtime的实例应该只有一个。所以应该使用单例来实现。 public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } private Runtime() {} } 以上代码为JDK中

单例模式二(懒汉式)

佐手、 提交于 2020-03-02 16:49:21
上一篇文章讲到了饿汉式有占用资源而不使用的嫌疑,那我们就应该考虑到调用的时候在生成对象。 改后的第一版本 public class LazySingletion { private LazySingletion(){ } private static LazySingletion single; protected static LazySingletion getInstance(){ if(single == null ){ single = new LazySingletion(); } return single; } } 这里先买个关子,大家看出了有这问题没? 1.0版本会有线程不安全的情况,在多线程下,会出现多个对象实例。 新建一个类实现Runnable接口 public class ExectorThread implements Runnable { public void run() { LazySingletion singleton = LazySingletion.getInstance(); System.out.println(Thread.currentThread().getName()+":"+singleton); } } 新建测试类 public class Test { public static void main(String[]

单例模式、读写锁

喜夏-厌秋 提交于 2020-03-02 10:18:06
单例模式 是设计模式中的一种,是大佬们针对典型场景设计的解决方案。 典型场景:一个对象/一个资源 只能被初始化加载一次 。 例如:你在打游戏的时候,游戏有很多图片资源。希望一个图片只加载一次。 实现方式 : 饿汉/懒汉 饿汉:所有资源在程序初始化阶段 一次性 完成初始化(资源在初始化的时候一次性全部加载,后续只需要使用就可以) template<class T> class single { static T _data;//所以实例化的对象共用同一份资源 T* get_instance() { return &_data; } } 资源初始化的时候会慢一点,但是运行起来以后,会很流畅。 懒汉:资源在 使用的时候 进行初始化(用到的时候再去加载,当然也要保证只加载一次) template <typename T> class Singleton { static T* inst; public: static T* GetInstance() { if (inst == NULL) { inst = new T(); } return inst; } } 在使用的时候加载一次资源,会涉及到线程安全问题。(volatile、static、mutex、二次判断) 使用static保证多个对象使用 同一份 空间资源。(保证资源只被加载一次,实现单例模式) 加锁保护资源申请过程

单例设计模式

荒凉一梦 提交于 2020-03-02 06:25:19
单例设计模式是面试中经常被问到的问题,今天将单例设计模式进行一个复习 单例设计模式 单例设计模式,一个类只有一个实例化对象,且类的构造方法私有化,单例设计模式有三个特点: 只有一个实例对象; 由类自行创建,构造方法私有化; 提供一个访问单例的全局访问点; 单例类的实现 1.懒汉模式 该模式,类加载时没有生成单例对象,只有第一次调用访问单例的方法才会才会穿件单例对象,代码如下: package singletonModel; public class lazySingleton { private static volatile lazySingleton instance = null; private lazySingleton() {}; public static lazySingleton getInstance() { if(instance == null) { instance = new lazySingleton(); } return instance; } } 2.饿汉模式 该模式的特点是,类一旦加载就创建一个单例,代码如下: package singletonModel; public class hungrySingleton { private static final hungrySingleton instance = new

【设计模式】单例模式

痴心易碎 提交于 2020-03-01 20:17:38
单例模式 优点 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。 2、避免对资源的多重占用(比如写文件操作)。 缺点 没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。 使用场景 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。 实现方式 1 懒汉式 注 这种方式采用双锁机制,安全且在多线程情况下能保持高性能。 getInstance() 的性能对应用程序很关键。 public class LazySingleton { //没有volatile其他线程可能由于指令重排访问到还没有初始化的对象 //volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作; private static volatile LazySingleton lazySingleton = null ; private LazySingleton ( ) { } public static LazySingleton getInstance ( ) { //双检锁/双重校验锁(DCL,即 double-checked locking) if ( lazySingleton == null ) {

单例设计模式实现总结

三世轮回 提交于 2020-03-01 19:16:29
单例模式的总体概述 单例模式,属于创建型模式,《设计模式》一书对它做了定义:保证一个类仅有一个实例,并提供一个全局访问点。 单例模式适用于无状态的工具类、全局信息类等场景。例如日志工具类,在系统中记录日志;假设我们需要统计网站的访问次数,可以设置一个全局计数器。 单例模式的优势有 在内存里只有一个实例,减少了内存开销; 可以避免对资源的多重占用; 设置全局访问点,严格控制访问。 单例模式的研究重点大概有以下几个: 构造私有,提供静态输出接口 线程安全,确保全局唯一 延迟初始化 防止反射攻击 防止序列化破坏单例模式 多种实现方式与比较 线程安全的饿汉模式 public class HungrySingleton { private final static HungrySingleton instance = new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getInstance() { return instance; } } 也可以通过静态代码块的形式实现。实现与静态常量基本相同,只是把实例化过程放到了静态代码块中。 private final static HungrySingleton2 instance; static { instance = new

小博老师解析Java核心技术 ——单例模式的运用

心已入冬 提交于 2020-03-01 10:09:49
[ 引言 ] 我们在学习 软件开发 面向对象编程思想的时候,要深入理解面向对象的设计思想,就会接触到一些设计模式。其中单例模式就是一个使用和面试频度相当高的设计模式。今天小博老师就为大家讲解 单例模式 的运用案例。 [ 步骤阅读一 ] 单例模式的作用 我们首先来制作一个简单的Java窗体程序,程序启动后实例化登录窗体,在登录窗体中点击“注册”按钮后,会弹出注册窗体。登录窗体核心代码如下: package com.bwf.technology.javase.jswing; import java .awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class BWFLogin extends JFrame{ public BWFLogin(){ super ("www.51code.com"); setBounds(200, 100, 320, 245)

设计模式学习笔记(二)——单例模式详解

岁酱吖の 提交于 2020-03-01 01:33:48
1 概念 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。 GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。 2 为什么使用单例模式 在应用系统开发中,我们常常有以下需求: 在多个线程之间,比如初始化一次socket资源;比如servlet环境,共享同一个资源或者操作同一个对象 在整个程序空间使用全局变量,共享资源 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。 因为Singleton模式可以保证为一个类只生成唯一的实例对象,所以这些情况,Singleton模式就派上用场了。 3实现单例步骤常用步骤 a) 构造函数私有化 b) 提供一个全局的静态方法(全局访问点) c) 在类中定义一个静态指针,指向本类的变量的静态变量指针 **饿汉式:**即静态初始化的方式,它是类一加载就实例化的对象(实例化对象 new放在main函数外面),所以要提前占用系统资源。 **懒汉式:**有需要的时候再实例化对象。 4 示例代码a:普通懒汉式(多线程不安全) # include <iostream> using namespace std ; //////////////////0 普通懒汉式 (多线程不安全)///////////////////////