建筑设计公司英文,优化推广排名网站教程,做地方网站论坛,wordpress 老板页多例#xff1a;只是单例的一种延伸 不必过于在意各种模式的名字#xff0c;重要的是学会融会贯通#xff0c;把生产的car放到集合中 类似JDBC 的连接池 把连接对象放到池中 多例模式特点#xff1a; 1. 多例类可以有多个实例 2. 多例类必须自己创建自己的实例只是单例的一种延伸 不必过于在意各种模式的名字重要的是学会融会贯通把生产的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 ListCar1 list new ArrayListCar1();//用于存放多个实例的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 LockDCL方式 此方法的“Double-Check”体现在进行了两次 if (singleton null) 的检查这样既同步代码块保证了线程安全同时实例化的代码也只会执行一次实例化后同步操作不会再被执行从而效率提升很多详细比较见附录 1。 双重检查锁定DCL方式也是延迟加载的它唯一的问题是由于Java 编译器允许处理器乱序执行在JDK版本小于1.5时会有DCL失效的问题原因解释详见附录 2。当然现在大家使用的JDK普遍都已超过1.4只要在定义单例时加上1.5及以上版本具体化了的volatile关键字即可保证执行的顺序从而使单例起效。所以 DCL 方式是推荐的一种方式。