单例模式在网上已经是被写烂的一种设计模式了,笔者也看了不少的有关单例模式的文章,但是在实际生产中使用的并不是很多,如果一个知识点,你看过100遍,但是一次也没实践过,那么它终究不是属于你的。因此我借助这篇文章来复习下设计模式中的单例模式。
在Java多线程编程-(2)中提及到了一段使用Synchronized关键字实现的单利模式--双重校验锁,代码如下:
一个男人只能有一个媳妇「正常情况」,一个人只能有一张嘴,通常一个公司只有一个 CEO ,一个狼群中只有一个狼王等等
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
今天给大家介绍《Java极简设计模式》的第01章,单例设计模式(Singleton),多一句没有,少一句不行,用最简短的篇幅讲述设计模式最核心的知识,好了,开始今天的内容。
2.构造方法若是public权限,对于类的外部,就能随意创建对象,无法控制对象个数
从问题来看,大家讨论的问题的焦点在于 map 去 put 一个对象的时候,究竟会不会因为对象没有完全初始化完成而导致另外一个线程 get 的时候只是拿到了对象的引用,导致报错呢?
单例模式,顾名思义,在程序运行时有且仅有一个实例存在。最常见的一个应用场景就是网站访问量的计数器,试想如果允许创建多个实例,那还怎么计数,这个时候就得创建有且仅有的一个实例了。如何防止程序创建多个实例呢?首先就是不能直接new。不能new那就是要将构造函数实例化,那怎么来创建实例呢?我们还是从代码着手。 1 package day_5_singleton; 2 3 /** 4 * 单例 5 * @author turbo 6 * 7 * 2016年9月8日 8 */ 9 pub
单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)–来自百度百科
指令重排是编译器或者CPU为了优化代码执行效率, 减少CPU的执行时钟周期而进行的优化操作; 这只是CPU众多优化的一种.
打算开始打理我的公众号了,最新内容和独家秘籍。走过路过来捧个场,关注公众号:编程之王
上一篇我们对经典的单例模式进行了学习,并且知道了单例模式的概念,以及如何通过单线程去创建一个有效的单例模式,让程序不用多次去创建实例。
单例模式(Singleton Pattern)是设计模式中一个重要的模式之一,是确保一个类在任何情况下都绝对只有一个实例。单例模式一般会屏蔽构造器,单例对象提供一个全局访问点,属于创建型模式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
拖了很久的文章终于动笔了,两个月前提的PR现在才开始写总结文章,lazydog一只....
发布对象:使一个对象能够被当前范围之外的代码所使用。 对象溢出:是一种错误的发布,当一个对象还没有构造完成时,就使它被其他线程所见。
本文主要参考Doug Lea(大神)的《Scalable IO in Java》中讲述的Reactor模式。
单例 是最为最常见的设计模式之一。对于任何时刻,如果某个类只存在且最多存在一个具体的实例,那么我们称这种设计模式为单例。例如,对于 class Mouse (不是动物的mouse哦),我们应将其设计为 singleton 模式。
看几个单例对象的示例代码,其中有些代码是线程安全的,有些则不是线程安全的,需要大家细细品味,这些代码也是冰河本人在高并发环境下测试验证过的。
1、Java语言为了解决并发编程中存在的原子性、可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized、volatile、final、concurren包等。
理想情况来讲,开发在开始编写代码之前就应该讲并发情况考虑进去,但是大多数实际情况确是,开发压根不会考虑高并发情况下的业务问题。主要原因还是因为业务极难遇到高并发的情况。
单例模式是应用最广的模式之一,也是23种设计模式中最基本的一个。本文旨在总结通过Java实现单例模式的各个版本的优缺点及适用场景,详细分析如何实现线程安全的单例模式,并探讨单例模式的一些扩展。
单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好、用对单例模式,还真得费一番脑筋。本文对Java中常见的单例模式写法做了一个总结,如有错漏之处,恳请读者指正。
在我的博客和公众号中,发表过很多篇关于并发编程的文章,之前的文章中我们介绍过了两个在Java并发编程中比较重要的两个关键字:synchronized和volatile
单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
计算机通电 -> CPU读取内存中程序(电信号输入)->时钟发生器不断震荡通断电 ->推动CPU内部一步一步执行(执行多少步取决于指令需要的时钟周期)->计算完成->写回(电信号)->写给显卡输出(sout,或者图形)
单例的目的是为了保证某个类只实例化一个对象。对于我们来说,理解这些单例写法的不同点,最好的方法是明白他们在什么情况下会失效。
纠结单例模式有几种写法有用吗?有点用,面试中经常选择其中一种或几种写法作为话头,考查设计模式和coding style的同时,还很容易扩展到其他问题。这里讲解几种猴哥常用的写法,但切忌生搬硬套,去记“茴香豆的写法”。编程最大的乐趣在于“know everything, control everything”。
根据大神Doug Lea 在 《Scalable IO in Java 》中的介绍,Reacotr模型主要分为三个角色
单例模式写法有很多,于是我看到了这么一种写法: public class SingletonTest {
对于多线程的理解不是非常深刻,工作中用到多线程代码的机会也不多,前不久遇到了一个使用场景,通过编码实现后对于多线程的理解和应用有了更加深刻的理解。场景如下:现有给用户发送产品调研的需求,运营的同事拿来了一个Excel文件,要求给Excel里面大约六万个手机号发送调研短信。
在我前面有写过一篇关于单例模式的几种创建的文章,最近在看多线程的时候,发现如果使用双重检验锁则可能会发生问题,接下来看我细细道来
从Java内存模型出发,结合并发编程中的原子性、可见性、有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景;在这补充一点,分析下volatile是怎么在单例模式中避免双检锁出现的问题的。
众所周知,Redis是一个高性能的数据存储框架,在高并发的系统设计中,Redis也是一个比较关键的组件,是我们提升系统性能的一大利器。深入去理解Redis高性能的原理显得越发重要,当然Redis的高性能设计是一个系统性的工程,涉及到很多内容,本文重点关注Redis的IO模型,以及基于IO模型的线程模型。
懒汉式单例:通过判断单例对象是否为null和加同步关键字,保证只在第一次使用单例类创建单例类,避免创建重量级单例类慢的问题。在高并发情况下,同步关键字的使用可能会降低性能
顾名思义,饿汉法就是在第一次引用该类的时候就创建对象实例,而不管实际是否需要创建。代码如下:
很多人上来肯定一脸懵逼,因为在你的印象中,单例模式实现起来还是很简单的。不要着急,慢慢往下看,你就知道为什么我说它最难了。 1. 基本概念 单例模式是一种常用的创建型设计模式。单例模式保证类仅有一个实例,并提供一个全局访问点。 2. 适用场景 想确保任何情况下都绝对只有一个实例。 典型的场景有:windows 的任务管理器、windows 的回收站、线程池的设计等。 3. 单例模式的优缺点 优点 内存中只有一个实例,减少了内存开销。 可以避免对资源的多重占用。 设置全局访问点,严格控制访问
个人理解,单例是指单个实例,在整个应用程序当中有且仅有一个实例存在,该实例是通过代码指定好的(自行创建的)。
本篇文章,我们一起来看下System.currentTimeMillis()的性能问题。
这个步骤前后是不确定的。当线程一运行到1处的时候可能会先对象赋值给single了但是此时的single还没有初始化完成。线程2运行的0处的时候会发现这个条件是不符合的于是就返回了single。这时候的single虽然是一个非空的引用,但却不是一个正确的对象。这个就是双重校验可能出现的问题。
来源:http://www.tekbroaden.com/singleton-java.html
“你知道茴香豆的‘茴’字有几种写法吗?” 纠结单例模式有几种写法有用吗?有点用,面试中经常选择其中一种或几种写法作为话头,考查设计模式和coding style的同时,还很容易扩展到其他问题。这里讲解几种猴哥常用的写法,但切忌生搬硬套,去记“茴香豆的写法”。编程最大的乐趣在于“know everything, control everything”。 大体可分为4类,下面分别介绍他们的基本形式、变种及特点。 饱汉模式 饱汉是变种最多的单例模式。我们从饱汉出发,通过其变种逐渐了解实现单例模式时需要关注的问题。
来 源:http://www.tekbroaden.com/singleton-java.html
高性能的服务器,不一定是多线程实现的,也就是说多线程不一定比单线程效率高,这得分具体的情况。以redis为例,核心处理请求的线程只有一个,所以我们常常理解其仅仅只有一个线程,但准确来说其实并不是单线程的,比如日志的备份需要单独的fork一个进程或者线程去做备份等,那么redis何来单线程还能达到如此10万+的qps呢?其实这取决于具体的实现,redis采用了基于高性能Reactor的IO多路复用的模式+内存数据结构+单线程处理网络请求这几块,决定了其性能高的原因。
DCL双检测锁机制: 用DCL双检测锁机制为什么要用valoatile修饰,因为lazyMan=new LazyMan(), 并非是一个原子操作。事实上在JVM中大概做了3件事。
单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好、用对单例模式,还真得费一番脑筋。本文对 Java 中常见的单例模式写法做了一个总结,如有错漏之处,恳请读者指正。
领取专属 10元无门槛券
手把手带您无忧上云