如何实现单例模式
单例模式实现方式有以下五种:
1、饿汉模式。线程安全,调用效率高,不能延时加载。
2、懒汉模式。线程安全,调用效率不高,能延时加载。
3、双重检测锁模式。由因JVM底层模型原因,偶尔会出问题,不建议使用。
4、静态内部类式。线程安全,调用效率高,可以延时加载。
5、枚举类。线程安全,调用效率高,不能延时加载,可防止反射和反序列化调用。
如何写一个简单的单例模式?
简单的单例模式如下[java]view plaincopyprint?public class Singleton{private static Singleton unique Instance=null;private Singleton(){//Exists only to defeat instantiation.}public static Singleton getInstance(){if(unique Instance==null){unique Instance=new Singleton();}return unique Instance;}//Other methods...}单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。扩展资料一、单例模式有以下特点:1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。二、单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。1.饿汉式单例类[java]view plaincopyprint?//饿汉式单例类.在类初始化时,已经自行实例化public class Singleton1{//私有的默认构造子private Singleton1(){}//已经自行实例化private static final Singleton1 single=new Singleton1();//静态工厂方法public static Singleton1 getInstance(){return single;}}2.懒汉式单例类[java]view plaincopyprint?//懒汉式单例类.在第一次调用的时候实例化public class Singleton2{//私有的默认构造子private Singleton2(){}//注意,这里没有finalprivate static Singleton2 single=null;//静态工厂方法public synchronized static Singleton2 getInstance(){if(single==null){single=new Singleton2();}return single;}}3.登记式单例类[java]view plaincopyprint?import java.util.HashMap;import java.util.Map;//登记式单例类.//类似Spring里面的方法,将类名注册,下次从里面直接获取。public class Singleton3{private static Mapmap=new HashMap();static{Singleton3 single=new Singleton3();map.put(single.getClass().getName(),single);}//保护的默认构造子protected Singleton3(){}//静态工厂方法,返还此类惟一的实例public static Singleton3 getInstance(Stringname){if(name==null){name=Singleton3.class.getName();System.out.println("name==null"+"--->name="+name);}if(map.get(name)==null){try{map.put(name,(Singleton3)Class.forName(name).newInstance());}catch(InstantiationExceptione){e.printStackTrace();}catch(IllegalAccessExceptione){e.printStackTrace();}catch(ClassNotFoundExceptione){e.printStackTrace();}}returnmap.get(name);}//一个示意性的商业方法public String about(){return"Hello,IamRegSingleton.";}public static void main(String[]args){Singleton3 single3=Singleton3.getInstance(null);System.out.println(single3.about());}}参考资料:百度百科——java单例模式
你熟悉的设计模式有哪些?写出单例模式的实现代码
23个设计模式:根据目的设计模式可以分为创造模式,结构模式和行为模式,创建模式用于处理对象的创建。结构模式用于处理类或对象的组合。行为模式用于描述类或对象如何交互以及如何分配职责,创建模式用于处理对象的创建。主要包括以下五种设计模式:工厂方法模式()抽象工厂模式(AbstractFactoryPattern)建造者模式(BuilderPattern)原型模式(PrototypePattern)单例模式(SingletonPattern)结构模式用于处理类或对象的组合,包括以下七个设计模式:适配器模式(AdapterPattern)桥接模式(BridgePattern)组合模式(CompositePattern)装饰者模式(DecoratorPattern)外观模式(FacadePattern)享元模式(FlyweightPattern)代理模式(ProxyPattern)行为模式描述类或对象如何交互以及它们如何分配职责。它由以下11种设计模式组成:责任链模式(Chain的ResponsibilityPattern)命令模式(CommandPattern)解释器模式(InterpreterPattern)迭代器模式(IteratorPattern)中介者模式(MediatorPattern)备忘录模式(MementoPattern)观察者模式(ObserverPattern)状态模式(StatePattern)策略模式(StrategyPattern)模板方法模式(TemplateMethodPattern)访问者模式(VisitorPattern)单例模式实现1:公共类Singleton{类共享实例对象私有静态单例;单例=零;//私有构造函数私有Singleton(){系统。出去了。这是单例!!);}//获取单例方法公共同步静态单例getInstance(){//确定共享对象是否为空,如何空一个新对象If(singleton==null){singleton=newsingleton();}返回单例。}}单例模式实现2:公共类Singleton{类共享实例对象实例化PrivatestaticSingletonSingleton=newSingleton();//私有构造函数私有Singleton(){系统:出去了,这是单例!!);}//获取单例方法公共静态单例getInstance(){直接返回共享对象返回单例。}}扩展资料:注意事项:设计模式主要分三个类型:创建型和行为型。Singleton:确保一个类只有一个实例,并为其提供一个全局访问点AbstractFactory:提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。FactoryMethod:定义一个用于创建对象的接口,并让子类决定实例化哪个类。工厂方法将类的实例化延迟到子类。Builder:将复杂对象的构造与其表示分离,使相同的构造过程可以创建不同的表示。Prototype:指定要使用Prototype实例创建的对象的类型,并复制该原型来创建一个新对象。Composite:将对象组合成树状结构,以表示整体各部分之间的关系。组合使用户一致地使用单个对象和组合对象。Facade:为子系统fa中的一组接口提供一致的接口。Ade提供了一个高级接口,使子系统更易于使用。Proxy:为其他对象提供一个代理,以控制对该对象的访问Adapter:将一个接口类转换为客户想要的另一个接口类。适配器模式使那些由于接口不兼容而无法一起工作的类一起工作。Decrator:式比子类化更灵活,可以为对象动态添加一些额外的职责。Bridge:模式将抽象部分与其实现部分分离,以便它们可以独立地更改。Flyweight:享元模式
设计模式之单例模式
本文开始整个设计模式的系列学习,希望通过不断的学习,可以对设计模式有整体的掌握,并在项目中根据实际的情况加以利用。
单例模式是指一个类仅允许创建其自身的一个实例,并提供对该实例的访问权限。它包含静态变量,可以容纳其自身的唯一和私有实例。它被应用于这种场景——用户希望类的实例被约束为一个对象。在需要单个对象来协调整个系统时,它会很有帮助。
1、单例类只能有一个实例
2、单例类必须自己创建自己的唯一实例
3、单例类必须给其他所有对象提供这一实例
1.尽量使用懒加载
2.双重检索实现线程安全
3.构造方法为private
4.定义静态的Singleton instance对象和getInstance()方法
单例模式至少有六种写法。
作为一种重要的设计模式,单例模式的好处有:
1、控制资源的使用,通过线程同步来控制资源的并发访问
2、控制实例的产生,以达到节约资源的目的
3、控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。但其实通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。
虽然也是只有一个线程能够执行,假如线程B先执行,线程B获得锁,线程B执行完之后,线程 A获得锁,但是此时没有检查singleton是否为空就直接执行了,所以还会出现两个singleton实例的情况。
既然懒汉式是非线程安全的,那就要改进它。最直接的想法是,给getInstance方法加锁不就好了,但是我们不需要给方法全部加锁啊,只需要给方法的一部分加锁就好了。基于这个考虑,引入了双检锁(Double Check Lock,简称DCL)的写法:
使用volatile 的原因:
对于JVM而言,它执行的是一个个Java指令。在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为新的Singleton实例分配空间, 然后直接赋值给instance成员,然后再去初始化这个Singleton实例。这样就使出错成为了可能,我们仍然以A、B两个线程为例:
加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。
枚举类实现单例模式是 effective java 作者极力推荐的单例实现模式,因为枚举类型是线程安全的,并且只会装载一次,设计者充分的利用了枚举的这个特性来实现单例模式,枚举的写法非常简单,而且枚举类型是所用单例实现中唯一一种不会被破坏的单例实现模式。因为枚举类没有构造方法,可以防止反序列化操作。
1、除枚举方式外, 其他方法都会通过反射的方式破坏单例,反射是通过调用构造方法生成新的对象,所以如果我们想要阻止单例破坏,可以在构造方法中进行判断,若已有实例, 则阻止生成新的实例,解决办法如下:
2、如果单例类实现了序列化接口Serializable, 就可以通过反序列化破坏单例,所以我们可以不实现序列化接口,如果非得实现序列化接口,可以重写反序列化方法readResolve(), 反序列化时直接返回相关单例对象。
Runtime是一个典型的例子,看下JDK API对于这个类的解释"每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接,可以通过getRuntime方法获取当前运行时。应用程序不能创建自己的Runtime类实例。",这段话,有两点很重要:
1、每个应用程序都有一个Runtime类实例
2、应用程序不能创建自己的Runtime类实例
只有一个、不能自己创建,是不是典型的单例模式?看一下,Runtime类的写法:
为了节约系统资源,有时需要确保系统中某个类只有唯一一个实例,当这个唯一实例创建成功之后,我们无法再创建一个同类型的其他对象,所有的操作都只能基于这个唯一实例。为了确保对象的唯一性,我们可以通过单例模式来实现。
单例模式应用的场景一般发现在以下条件下:
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
关于单例模式的漫画分析: https://mp.weixin.qq.com/s/f-sJIZHr7JUa31gKTllSFQ
单例模式的优缺点、注意事项、使用场景
设计模式 之 单例模式
1. 定义 单例模式指的是一个类,在全局范围内(整个系统中)有且只能有一个实例存在。即该类本身负责提供一种访问其唯一对象的方式,不对外提供公共的构造函数(禁用默认公共构造函数),对于该类的实例化由它自己在类的内部进行维护! 2. 优缺点 - 优点 1. 最大程度的减少了对象的创建和销毁的次数,从而降低的垃圾回收的次数 2. 节约了系统资源,尤其是内存资源 - 缺点 1. 不能继承,不能被外部实例化 2. 类干预了外部类的使用(外部实用类不能随意实例化),而不再仅仅专注于内部的逻辑(与单一职责模式有矛盾) 3. 使用场景 - 有频繁的实例化后又销毁的情况,适合考虑使用单例模式,如记录日志的log对象 - 创建对象需要消耗过多的系统资源,但又经常用到的资源,如数据库连接 4. 框架中的应用 5. 实现方式 单例模式有多种实现方式,要考虑到多线程下的安全性,其每种实现方式如下所示: 以上方式,如果存在多个线程同时访问getInstance()时,由于没有锁机制,会导致实例化出现两个实例的情况,因此,在多线程环境下时不安全的。 如上代码所示,在getInstance()方法上添加了同步锁。但是该方法虽然解决了线程安全的问题,但却也带来了另外的一个问题,就是每次获取对象时,都要先获取锁,并发性能很差,还需要继续优化! 该方法将方法上的锁去掉了,避免了每次调用该方法都要获取锁的操作,从而提升了并发性能,同时在方法内部使用锁,进而解决了并发的问题,从而解决了上面**并发安全+性能低效**的问题,是个不错的实现单例的方式。 该方式虽然简单也安全,但是会造成再不需要实例时,产生垃圾对象,造成资源狼粪,因此,一般不使用。 这种方式可以达到跟** 双重校验锁 **一样的效果,但只适用于静态域的情况,双重校验锁可在实例域需要延迟初始化时使用 这是实现单例模式的最佳方法,更加简洁,自动支持序列化,防止多次实例化,非常高效! (强烈推荐使用) 6.引用