多例模式

多例:只是单例的一种延伸   不必过于在意各种模式的名字,重要的是学会融会贯通,把生产的car放到集合中 类似JDBC 的连接池 把连接对象放到池中

多例模式特点:
     1. 多例类可以有多个实例
     2. 多例类必须自己创建自己的实例,并管理自己的实例,和向外界提供自己的实例

package com.pers.hoobey;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Car1 {
  private static Car1 car1 = new Car1();
  private static Car1 car2 = new Car1();
  private static List<Car1> list = new ArrayList<Car1>();//用于存放多个实例的car
  private static final int maxCount =2;//最多的实例数
  static{
    list.add(car1);
    list.add(car2);
  }
  private Car1(){}//私有构造方法 避免外部创建实例
/*
* @description 指定拿取某一个实例
*/
  public static Car1 getInstance(int index){
    return list.get(index);
  }
  //随机拿取实例
  public static Car1 getInstance(){
    Random random = new Random();
    int current = random.nextInt(maxCount);
    return list.get(current);
}
public void run(){
System.out.println("奔跑中的车.....");
}
}

顺便总结一下 普通工厂模式 工厂方法模式和抽象工厂模式的区别:

简单工厂是用来生产”东西“的,那任何”东西“的子类,比如汽车,自行车,轮船,洗发水都是可以被生产的,但此处简单工厂的压力太大了啊,任何”东西“的子类都可以被生产,负担太重,所以一般对简单工厂类也有种称呼,叫”上帝类“。
而工厂方法模式就很好的减轻了工厂类的负担,把某一类/某一种东西交由一个工厂生产,同时增加某一类”东西“并不需要修改工厂类,只需要添加生产这类”东西“的工厂即可,使得工厂类符合开放-封闭原则。
对于”东西“的分类,有时候不能光是横向的分类,从另一个角度也是可以分类的,不知道这句话的意思能不能懂,打个比方:汽车可以根据品牌分为奔驰、奥迪,也可以根据类别分为普通三厢车和SUV车,如果用工厂方法来描述的话,奔驰车工厂有一个方法即生产奔驰车,奥迪车工厂有一个方法生产奥迪车,但在有多重分类的情形下,这样写已经不够用,不符合实际了,这个时候需要用到抽象工厂模式,即奥迪车工厂有两个方法,一个方法是生产普通三厢奥迪车,另一个方法是生产SUV奥迪车。奔驰车工厂有两个方法,一个方法是生产普通三厢奔驰车,另一个方法是生产SUV奔驰车。
上面即工厂方法模式和抽象工厂模式的应用场景,因为这两者很像,所以概念上不容易区分,可以这么说,工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的一种推广。

再说下抽象工厂模式,此处的抽象工厂接口应该是有两个方法,一个是生成普通三厢车,一个是生产SUV车,可以说,生产的”东西“已经被限定住了,因此你不能生产某品牌汽车外的其他”东西“,因而可以理解成使用抽象工厂模式不能新增新的”东西“(在简单工厂和工厂方法中理论上都是可以新增任意”东西“的)

 

下面分析一下懒汉模式下的单例模式

作为一个单例,我们首先要确保的就是实例的“唯一性”,有很多因素会导致“唯一性”失效,它们包括:多线程、序列化、反射、克隆等,更特殊一点的情况还有:分布式系统、多个类加载器等等。其中,多线程问题最为突出。为了提高应用的工作效率,现如今我们的工程中基本上都会用到多线程;目前使用单线程能轻松完成的任务,日复一日,随着业务逻辑的复杂化、用户数量的递增,也有可能要被升级为多线程处理。所以任何在多线程下不能保证单个实例的单例模式,我都认为应该立即被弃用。

在只考虑一个类加载器的情况下,“饿汉方式”实现的单例(在系统运行起来装载类的时候就进行初始化实例的操作,由JVM虚拟机来保证一个类的初始化方法在多线程环境中被正确加锁和同步,所以)是线程安全的,而“懒汉”方式则需要注意了,先来看一种最简单的“懒汉方式”的单例:

这种写法只能在单线程下使用。如果是多线程,可能发生一个线程通过并进入了 if (singleton == null) 判断语句块,但还未来得及创建新的实例时,另一个线程也通过了这个判断语句,两个线程最终都进行了创建,导致多个实例的产生。所以在多线程环境下必须摒弃此方式。

除了多并发的情况,实现单例模式时另一个重要的考量因素是效率。前述的“懒汉方式”的多线程问题可以通过加上 synchronized 修饰符解决,但考虑到性能,一定不要简单粗暴地将其添加在如下位置:

上述方式通过为 getInstence() 方法增加 synchronized 关键字,迫使每个线程在进入这个方法前,要先等候别的线程离开该方法,即不会有两个线程可以同时进入此方法执行 new Singleton(),从而保证了单例的有效。但它的致命缺陷是效率太低了,每个线程每次执行 getInstance() 方法获取类的实例时,都会进行同步。而事实上实例创建完成后,同步就变为不必要的开销了,这样做在高并发下必然会拖垮性能。所以此方法虽然可行但也不推荐。那我们将同步方法改为同步代码块是不是就能减少同步对性能的影响了呢:

但是这种同步却并不能做到线程安全,同最初的懒汉模式一个道理,它可能产生多个实例,所以亦不可行。我们必须再增加一个单例不为空的判断来确保线程安全,也就是所谓的“双重检查锁定”(Double Check Lock(DCL))方式:

此方法的“Double-Check”体现在进行了两次 if (singleton == null) 的检查,这样既同步代码块保证了线程安全,同时实例化的代码也只会执行一次,实例化后同步操作不会再被执行,从而效率提升很多(详细比较见附录 1)。

双重检查锁定(DCL)方式也是延迟加载的,它唯一的问题是,由于Java 编译器允许处理器乱序执行,在JDK版本小于1.5时会有DCL失效的问题(原因解释详见附录 2)。当然,现在大家使用的JDK普遍都已超过1.4,只要在定义单例时加上1.5及以上版本具体化了的volatile关键字,即可保证执行的顺序,从而使单例起效。所以 DCL 方式是推荐的一种方式。

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

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

相关文章

Oracle public view,【易错概念】以太坊Solidity函数的external/internal,public/private,view/pure/payable区别...

1. 函数类型&#xff1a;内部(internal)函数和外部(external)函数函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量&#xff0c;也可以将一个函数作为参数进行传递&#xff0c;还能在函数调用中返回函数类型变量。 函数类型有两类&#xff1a;- 内部(i…

ftp连接oracle服务器,使用SSL加密连接FTP - 架建SSL安全加密的FTP服务器(图)_服务器应用_Linux公社-Linux系统门户网站...

四、使用SSL加密连接FTP启用Serv-U服务器的SSL功能后&#xff0c;就可以利用此功能安全传输数据了&#xff0c;但FTP客户端程序必须支持SSL功能才行。 如果我们直接使用IE浏览器进行登录则会出现图4显示的错误信息&#xff0c;一方面是以为没有修改默认的端口21为990&#xff0…

oracle 微信公众号,关于微信公众号贴代码的方法

微信公众号码上贴代码一直一来都是个头疼的问题。吐槽一句&#xff1a;要是后台编辑器支持markdown就好了。今天教大家用在线markdown排版工具&#xff0c;把代码完美贴到微信公众号上。长话短说&#xff0c;今天用到的两个工具&#xff1a;首先&#xff0c;以一段代码为例。假…

计算理论 形式语言与自动机_下推式自动机(PDA)| 计算理论

计算理论 形式语言与自动机Pushdown Automaton (PDA) is a kind of Automaton which comes under the theory of Computation that appoints stack. The word Pushdown stands due to the fact that the stack can be pushed down as operations can only work on the elements…

运维人员究竟如何提升价值,持续获得高薪?

作者简介&#xff1a;老男孩&#xff0c;北京老男孩IT教育创始人&#xff0c;17年IT经验&#xff0c;资深Linux实战专家&#xff0c;IT培训界实战派顶尖大师&#xff0c;国内将实战心理学体系大量注入IT运维培训领域的第一人&#xff0c;多本IT畅销图书作者&#xff0c;51CTO金…

清空 linux 服务器,Linux服务器清理

Why?废话不多说直接来图&#xff0c;可以看出磁盘已经快要满了未清之前What?可以看出mnt文件夹占用的最大&#xff0c;然后进入mnt目录里通过命令,根据文件大小对该路径下文件排序du -h --max-depth1我们服务器出现磁盘快满了的原因是因为&#xff0c;服务器部署了多个tomcat…

Git中的AutoCRLF与SafeCRLF换行符问题

2019独角兽企业重金招聘Python工程师标准>>> 原文&#xff1a;http://www.cnblogs.com/flying_bat/archive/2013/09/16/3324769.html 最近在使用GitHub&#xff0c;发现不时没有修改过的文件要提交&#xff0c;对比发现文件全部修改&#xff0c;但找不到不一样的地方…

linux 下邮件服务器,Linux 下搭建Postfix邮件服务器

Linux 下搭建Postfix邮件服务器详解&#xff1a;1、首先关闭sendmail服务service sendmail stop2、chkconfig sendmail off(关闭开机自启动)3、修改DNS正解文件&#xff0c;使DNS能够解析邮箱服务添加下面两行mail.zhubf.com. IN A 172.17.17.2zhubf.com. IN M…

Coreseek Windows下安装调试

由于项目需要全文检索&#xff0c;后面就去网上查了下资料&#xff0c;找到了Sphinx【中文是狮身人面像】这个全文检索引擎&#xff0c;听说挺好用的&#xff0c;不过没有中文分词。后面又去找了一下&#xff0c;找到了Coreseek&#xff0c;一款中文全文检索/搜索软件。 一、Sp…

android shape.xml 属性详解

转载源:http://blog.csdn.net/harvic880925/article/details/41850723 一、简单使用 刚开始&#xff0c;就先不讲一堆标签的意义及用法&#xff0c;先简单看看shape标签怎么用。 1、新建shape文件 首先在res/drawable文件夹下&#xff0c;新建一个文件&#xff0c;命名为&#…

Linux比较大文件内容,Linux系统最大文件打开数优化,解决Too many open files报错

这是一个Linux系统常见的故障&#xff0c;网络上也能轻易的找到解决办法&#xff0c;我也只是在工作中遇到了这个问题&#xff0c;所以在博客记录下&#xff0c;以备不时之需。一、报错截图&#xff1a;图为resin的报错日志&#xff0c;很明显提示了Too many open files&#x…

Varnish缓存代理简介与配置

一、varnish原理&#xff1a;1&#xff09;Varnish简介&#xff1a;varnish缓存是web应用加速器&#xff0c;同时也作为http反向缓存代理。你可以安装varnish在任何http的前端&#xff0c;同时配置它缓存内容。与传统的 squid 相比&#xff0c;varnish 具有性能更高、速度更快、…

linux安装卸载mysql,Linux6 系列 安装、卸载mysql

Linux6 系列 安装、卸载mysqlLinux6 系列 安装、卸载mysqlLinux环境下载mysql&#xff1a;https://blog.csdn.net/weixin_40816738/article/details/90111456一、安装环境依赖&#xff1a;yum install -y cmake make gcc gcc-c libaio ncurses ncurses-devel二、安装流程1、软件…

linux14.04 Apache,Ubuntu 14.04编译安装Apache

Ubuntu下编译安装apache需要预先编译安装多个依赖件&#xff0c;包括&#xff1a;apr, apr-util,pcre,zlib-devel&#xff0c;等&#xff0c;相当麻烦&#xff0c;记录于此备查.由于Ubuntu系统默认安装时没有安装C&#xff0c;所以也需要先安装c编译需要相关的组件。[注]apt-ca…

linux dd入门,Linux基础知识:Linux中DD命令详解

1.dd命令简介功能&#xff1a;把指定的输入文件拷贝到指定的输出文件中&#xff0c;并且在拷贝过程中可以进行格式转换。可以用该命令实现DOS下的diskcopy命令的作用。先用dd命令把软盘上的数据写成硬盘的一个寄存文件&#xff0c;再把这个寄存文件写入第二张软盘上&#xff0c…

lcase和ucase_在SQL中使用UCASE(),LCASE()和MID()函数

lcase和ucaseUpper Case, Lower Case and MID functions are scalar functions which return a single value, based in the input value. 大写&#xff0c;小写和MID函数是标量函数&#xff0c;它们基于输入值返回单个值。 As you all know sometimes different databases ha…

linux ntp手动授时,关于我校NTP授时服务的使用说明

校园网用户&#xff1a;我中心于近期采购了GPS北斗授时服务设备&#xff0c;该设备可实现纯GPS模式、纯北斗模式和混合模式与卫星对时&#xff0c;同时实现对校内设备授时的功能。支持所有NTP协议的服务器、PC、嵌入式设备等&#xff0c;包括但不限于&#xff1a;Microsoft Win…

linux反序列化漏洞,思科多个产品Java反序列化漏洞(CVE-2015-6420)

思科多个产品Java反序列化漏洞(CVE-2015-6420)发布日期&#xff1a;2015-12-15更新日期&#xff1a;2015-12-17受影响系统&#xff1a;Cisco Unified ComputingCisco Voice and Unified Communications DevicesCisco Wireless描述&#xff1a;CVE(CAN) ID: CVE-2015-6420思科是…

密码学替代技术_替代技术及其类型| 密码学

密码学替代技术As we already discussed what are the Substitution techniques and one of its type Ceasar Cipher? So we are not discussing it here for that please refer to Cryptography: CeasarCipher here: Cryptography: Caesar Cipher and its Python Implementat…

Flask+uwsgi+Nginx环境搭建

2019独角兽企业重金招聘Python工程师标准>>> 开源软件准备 需要的软件列表&#xff1a; setuptools-33.1.1.zip Python-2.7.13.tgz pip-9.0.1.tar.gz nginx-1.10.3.tar.gz 软件统一上传到/usr/local/src/下&#xff0c;python是使用自己编译的。Python安装 先安装以…