单列模式

最近在学设计模式,学到创建型模式的时候,碰到单例模式(或叫单件模式),现在整理一下笔记。

  在《Design Patterns:Elements of Resuable Object-Oriented Software》中的定义是:Ensure a class only has one instance,and provide a global point of access to。它的主要特点不是根据客户程序调用生成一个新的实例,而是控制某个类型的实例数量-唯一一个。(《设计模式-基于C#的工程化实现及扩展》,王翔)。也就是说,单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。

  一、经典模式:

publicclass Singleton
{
privatestatic Singleton instance;

private Singleton()
{

}

publicstatic Singleton GetInstance()
{
if(instance==null)
{
instance
=new Singleton();
}
return instance;
}
}

  解析如下:

  1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;

  2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例;

  3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。

  在这种经典模式下,没有考虑线程并发获取实例问题,即可能出现两个线程同时获取instance实例,且此时其为null时,就会出现两个线程分别创建了instance,违反了单例规则。因此,需对上面代码修改。

  二、多线程下的单例模式

  1、Lazy模式

publicclass Singleton
{
privatestatic Singleton instance;
privatestaticobject _lock=newobject();

private Singleton()
{

}

publicstatic Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance
=new Singleton();
}
}
}
return instance;
}
}

  上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。

  2、饿汉模式

  这种模式的特点是自己主动实例。

publicsealedclass Singleton
{
privatestaticreadonly Singleton instance=new Singleton();

private Singleton()
{
}

publicstatic Singleton GetInstance()
{
returninstance;
}
}

  上面使用的readonly关键可以跟static一起使用,用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用GetInstance()后才实例化出唯一的单例对象。

 

转载于:https://www.cnblogs.com/cpetcoandy/archive/2011/11/10/2244407.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法之排序算法-直接插入排序

package com.ebiz.sort;import java.text.SimpleDateFormat; import java.util.Date;/*** author YHj* create 2019-07-29 8:56* 插入排序*/ public class Insert {public static void main(String[] args) {// int [] arr{101,34,119,1};int[] arr new int[80000];for (int i…

佳能g3800故障灯说明书_热水器维修电话|史密斯燃气热水器出现16故障码

热水器出现故障代码其实是一件很常见的事情,大多是住户的热水器都出现过这样的问题,为了防止这样的事情也发生在我身上,我熟读热水器说明书,终于参透其中的道理,那么接下来我为大家介绍史密斯燃气热水器出现16故障码。…

DrawImage内存不足问题

出现这种问题,分析如下: 1.图片太大,绘制完没有及时释放。所谓图片太大,一种是原始图片本身很大,一种是把小图片拉伸到很大的矩形区域显示。 2.图片格式不对或者参数不对。 3.图片不完整。比如图片只下载了一半&#x…

算法之排序算法-shell排序(交换法)

可以先看注释掉的分析,最后在看三层for循环 package com.ebiz.sort;import java.util.Arrays;/*** author YHj* create 2019-07-30 8:53* shell排序-交换法*/ public class Shell{public static void main(String[] args) {int [] arr{8,9,1,7,2,3,5,4,6};getResult(arr);// Sy…

git语言包安装_Git分布式版本管理系统快速入门指南

为什么要使用版本管理系统无论有没有使用过专业化工具,每个人都或多或少地有版本管理的需求。我们在做论文、写报告或者设计方案时,因为难以避免的不断改动,总会形成很多个不同的版本,我们可能会用“某某设计方案_20180910”这样加…

[html] 如何放大点击的区域?

[html] 如何放大点击的区域&#xff1f; <div class"button">点我</div><style>.button{position:relative;}.button::after{content:"";position:absolute;top:-10px;left:-10px;right:-10px;bottom:-10px;}</style>个人简介 我…

(十)、java内部类与内部类的闭包和回调

一、成员内部类 1.可以把一个内部类看做是一个成员。成员内部类可以无条件访问外部类的所有成员属性和成员方法。 class OutterClass {//外部类private int in 0;static int inn4;public OutterClass(int in) {this.in in;}class InnerClass { //内部类public void outpu…

vb.net中滚动条一直显示没有数据时也显示_Android Studio 中 System Trace 的新增功能...

Android Studio 中 System Trace 的新增功能在 Android Studio 4.0 中&#xff0c;我们已经对 CPU Profiler 的 UI 做了大量调整来提供更加直观的工作流记录&#xff0c;而在 Android Studio 4.1 中&#xff0c;我们基于开发者们的反馈对此功能进行了持续改进&#xff0c;并且新…

[html] DOM节点的根节点是不是body?

[html] DOM节点的根节点是不是body&#xff1f; 文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述&#xff0c;并定义了一种方式可以使从程序中对该结构进行访问&#xff0c;从而改变文档的结构&#xff0c;样式和内容。DOM 将文档解析为一个由节…

第一节 Memcached分布式缓存入门

关于Memcached的博文太多了&#xff0c;以下是个人学习的收集整理。 本节讨论问题: 简单介绍与应用下载安装注意事项简单测试Memcached分布式原理 一、介绍与应用 在常规的WEB开发下&#xff0c;基本都会利用到缓存用以降低对数据库的压力&#xff0c;提高访问速度。有时候缓存…

tomcat 拦截指定url_一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了

点击“ 程序员内点事 ”关注&#xff0c;选择“ 设置星标 ”坚持学习&#xff0c;好文每日送达&#xff01;周末有个小伙伴加我微信&#xff0c;向我请教了一个问题&#xff1a;老哥&#xff0c;「过滤器 (Filter) 和 拦截器 (Interceptor) 有啥区别啊&#xff1f;」 听到题目我…

[html] 如何使用纯html制作一个进度条?

[html] 如何使用纯html制作一个进度条&#xff1f; HTML中的progress () 元素用来显示一项任务的完成进度.虽然规范中没有规定该元素具体如何显示,浏览器开发商可以自己决定,但通常情况下,该元素都显示为一个进度条形式.个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后…

Java 多线程练习---创建两个子线程,每个线程交替输出“你好--来自线程***”...

|--需求说明 |--实现思路 1、创建一个类&#xff0c;实现Runnable&#xff0c;在这个类里面重写run()方法&#xff0c;在run()方法里面写一个20的for循环 2、创建一个类&#xff0c;实例化上面的类&#xff0c;用这个类的对象创建线程 |--代码内容 1 package cn.thread;2 3 /**…

关于Android的应用程序的发布的学习(一)

上一次写了一篇关于android应用程序打包成apk文件的签名&#xff0c;地址&#xff1a;http://blog.csdn.net/zqiang_55/article/details/6939170 最近再看sdk的时候发现其实在sdk中又了详细的少说明&#xff0c;现在将主要的翻译如下&#xff1a; 在Dev Gudie标签页中的Publish…

手动封装js的call和apply和bind和typeof和new方法

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣一起学习前后端知识 闲来无事做 不如敲代码今天讲一下js里面的callapply和bind和typeof方法的手动封装由于最近比较忙但是有时间就会记录一下平时学习工作的一些代码用来分享这边就不直接多说开始我们的直接代码书写…

js保留两位小数的函数_使用率低但功能强大的6个Excel函数公式应用技巧解读!...

在Excel函数公式中&#xff0c;有部分函数的使用率是比较低的&#xff0c;但是其功能也是非常强大的。一、Median函数。功能&#xff1a;返回一组数的中值。中值就是一组数的中间数值&#xff0c;如果参数包含的数值是偶数&#xff0c;Median函数将返回位于中间两个值的平均值。…

IP包的生成和发送接口(1)

http://blog.sina.com.cn/s/indexlist_1657348185_2.html IP包的生成和发送接口 (1) Linux内核中有3种基本的IP包生成器, 它们分别为ip_build_xmit(), ip_queue_xmit(), ip_build_and_send_pkt(). ip_build_and_send_pkt()是一简单的IP包头封装接口, 它接照输入包的路由添加一…

.net复习之七

表A&#xff1a; 表B&#xff1a; 1&#xff0e; SELECT * FROM A JOIN B ON A.Id B.Id 將顯示 9 條數據。 Inner join(等值连接)只返回两个表中联结字段相等的行 2&#xff0e; SELECT * FROM A LEFT JOIN B ON A.Id B.Id 將顯示 12 條數據…

原生js实现tab栏切换效果

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣一起学习前后端知识 运行效果 首先我们来看一下原生js实现的效果 下面就开始直接上代码了 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

线程八大核心+java并发核心知识体系精讲_Java从业者如果不懂这些,面试80%都会挂在这些核心知识上面...

JVM无论什么级别的Java从业者&#xff0c;JVM都是进阶时必须迈过的坎。不管是工作还是面试中&#xff0c;JVM都是必考题。如果不懂JVM的话&#xff0c;薪酬会非常吃亏(近70%的面试者挂在JVM上了)详细介绍了JVM有关于线程、内存模型、JVM运行时内存、垃圾回收与算法、Java中四种…