多线程学习笔记二

单例设计模式与多线程:
设计模式:对问题行之有效的解决方式。其实是一种思想。
单例设计模式:
解决的问题:可以保证一个类在内存中的对象唯一性。
比如对于多个程序使用同一个配置信息对象时,都需要保证对象的唯一性。
如果保证唯一性?
1.不允许其他程序用new创建该类对象。
2.在该类中创建一个本类实例。
3.对外提供一个方法,让其他程序可以获取对象。
实现步骤:
1.私有化该类的构造函数。
2.通过new在本类中创建一个本类对象。
3.定义一个共有的方法,将创建的对象返回。

class Single{
        private Single(){}

        Single s = new Single();

        public void getInstance(){
            return s;
        }
    }    

接下来我们要如何调用这个对象呢?通过私有化Single类的构造函数,已经组织了我们new该类,那么就要通过类名.getInstance();的形式获得该类的对象。
所以该方法必须是静态的,因为该方法要返回s,所以s也要是静态的。

class Single{
        private Single(){}

        static Single s = new Single();

        public static void getInstance(){
            return s;
        }
    }

因为s为成员变量,所以我们可以通过类名.s的形式即Single.s的方法获得该类的对象,为什么还有弄一个方法呢?
通过方法的访问可以实现可控性。例如我可以在方法中传一个参数,只要传入的参数满足某个条件才返回s,这叫可控性。
s为Single类的成员变量,我们一般不会吧成员变量暴露出去,原因就是为了可控。

class Single{
        private Single(){}

        private static Single s = new Single();

        public static void getInstance(){
            return s;
        }
    }

以上为单例模式的基本思想。只要在任何一个类中加入以上代码,就能保证该类对象的唯一性。
这种方法类一加载就创建对象。下面介绍另外一种:

class Single{
        private Single(){}

        private static Single s = null;

        public static void getInstance(){
            if(s == null){
                s = new Single();
                return s;
            }
        }
    }

以上这种形式是当调用方法时才创建对象。也称为延迟加载形式。
为了区分两种形式:第一种叫做饿汉式,第二种叫做懒汉式。开发用饿汉式,面试用懒汉式,因为懒汉式包含的知识点比较多。
懒汉式在多线程中会有安全隐患问题。
为什么饿汉式没有呢?
多线程的安全问题发生的原因除了有多个线程共同访问一个共享资源外,还有一个原因就是执行操作共享数据的代码有多条。
而饿汉式只有一条-->return s;所以不会发生安全问题。
解决饿汉式:

class Single{
        private Single(){}

        private static Single s = null;

        public static synchronized void getInstance(){
            if(s == null){
                s = new Single();
                return s;
            }
        }
    }

但是上述解决方法每次调用该方法的时候都会判断锁,降低了效率。为了提高效率我们对该代码进行改写,不用同步函数锁,改用同步块锁。

class Single{
        private Single(){}

        private static Single s = null;

        public static void getInstance(){
            if(s == null){
                synchronized(Single.class){//注意:此方法为静态方法不能用this;
                    if(s == null){
                        s = new Single();
                        return s;
                    }
                }
            }
        }
    }

解释:使用同步块锁是为了解决线程安全问题,多加一次判断是为了提高效率。
综上所述:开发还是用饿汉式好。

时间: 2024-11-03 21:22:25

多线程学习笔记二的相关文章

Spring Batch学习笔记二

此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch的架构 一个Batch Job是指一系列有序的Step的集合,它们作为预定义流程的一部分而被执行: Step代表一个自定义的工作单元,它是Job的主要构件块:每一个Step由三部分组成:ItemReader.ItemProcessor.ItemWriter:这三个部分将执行在每一条被处理的记录上,ItemReader读取每一条记录,然后传递给ItemProcessor处理,最后交给ItemWriter做持久化:It

Android学习笔记二

17. 在ContentProvider中定义的getType()方法是定义URI的内容类型. 18. SQLiteDatabase类中的insert/delete/update/query方法其实也挺好用的,我在EquipmentProvider类中做了实现 19. Android专门有个单元测试项目(Android Test Project),在这个项目中,可以新建一个继承AndroidTestCase类的具体测试类来单元测试某个功能.我新建了一个AndroidTestProject项目,在

Win32 多线程学习笔记

学到的API函数 一.线程 创建线程.结束线程.获取线程的结束码 CreateThread ExitThread GetExitCodeThread 二.线程结束时触发 创建线程之后,等待线程的结束之后,再继续执行 WaitForSingleObject 创建多个线程之后,等待一组线程(或其中的一个)结束,再继续执行 WaitForMultipleObjects 将消息循环与内核对象的等待合并 MsgWaitForMultipleObjects 三.同步 SendMessage 是同步的 Pos

Caliburn.Micro学习笔记(二)----Actions

Caliburn.Micro学习笔记(二)----Actions 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions,看一下Caliburn.Micro给我们提供了多强大的支持 我们还是从做例子开始 demo的源码下载在文章的最后 例子1.无参数方法调用 点击button把textBox输入的文本弹出来 如果textbox里没有文本button不可点,看一下效果图 看一下前台代码 <Stac

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

JavaScript--基于对象的脚本语言学习笔记(二)

第二部分:DOM编程 1.文档象模型(DOM)提供了访问结构化文档的一种方式,很多语言自己的DOM解析器. DOM解析器就是完成结构化文档和DOM树之间的转换关系. DOM解析器解析结构化文档:将磁盘上的结构化文档转换成内存中的DOM树 从DOM树输出结构化文档:将内存中的DOM树转换成磁盘上的结构化文档 2.DOM模型扩展了HTML元素,为几乎所有的HTML元素都新增了innerHTML属性,该属性代表该元素的"内容",即返回的某个元素的开始标签.结束标签之间的字符串内容(不包含其它

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t