设计模式对于很多小伙伴来说都是它认识你,但是你不认识它,设计模式可以帮助我们简化代码,提高代码的复用率,减少代码的耦合性,以及增加代码的重复利用性,但是设计模式并非是好用的代言,有些时候也会给我们代来很多问题,比如简单的判断语句会变成复杂的多类关联,也会引发一些安全问题,比如今天要说的单例模式。 单例模式(Singleton Pattern)是Java中最简单的设计模式之一(暗藏玄机)。属于创建模式之一,提供了一种创建对象的最佳方式。一个单一的类,负责创建自己的对象,同时保证只有单个对象被创建,对外提供唯一的方法来获取该类的对象,并且不需要实例化对象。因此可以总结出以下几点: 一个被全局使用的类,被频繁的创建,当你想控制资源,节省资源时,你就要使用单例模式。 1、饿汉式 2、懒汉式,不考虑并发 3、懒汉式,加锁 4、懒汉式,双重检查代替方法锁,提高效率,防止指令重排加入volatile 5、懒加载、静态内部类实现。 6、枚举 以上都可以通过反射获取新的实例,枚举类被反射会直接触发异常 该方法在1.5才开始引入,不受众,不过是小黄书推荐的方式。 以上就是单例模式创建的方式,优点缺点,希望可以对大家有所帮助 。开篇
基本介绍
主要解决
关键代码
使用场景
缺点
具体实现并带有优缺点分析
/** * 饿汉式 * 利用classload上来初始化实例,解决并发问题 * 但是此方法比较大的问题就是,当初始化单利比较耗时,或者很久不会使用的时候,浪费内存 * 是最长用方案 */ public class SingleObject { //单例模式必然是上来就私有化 private SingleObject() { } //创建一个唯一的类对象 private static SingleObject instance = new SingleObject(); //提供一个获取的方法 public static SingleObject getInstance() { return instance; } }
/** * 因此引出懒汉式,节省内存 * 但是此情况又会出现线程并发问题 * 在判断 instance == null 的时候可能出现并发,多线程同时到达new */ class SingleObjectLazy { //依然是上来私有构造 private SingleObjectLazy() { } //创建静态对象变量,不初始化 private static SingleObjectLazy instance; //使用时在初始化 public static SingleObjectLazy getInstance() { if (instance == null) { instance = new SingleObjectLazy(); } return instance; } }
/** * 由于并发引出加锁, * 但是很难出现同时获取instance而且还是为空的情况 * 一旦创建后,不在需要锁住 * 此时就会造成效率低下 */ class SingleObjectSyncLazy { private SingleObjectSyncLazy() { } private static SingleObjectSyncLazy instance; public static synchronized SingleObjectSyncLazy getInstance() { if (instance == null) instance = new SingleObjectSyncLazy(); return instance; } }
/** * 使用双重检查机制 * 只有当并发null的时候才需要进入加锁,此时并发的概率很小 * 还是有问题的,不加上 volatile修饰的话,会出指令重排 * 同时 synchronized 只保单线程的结果正确,不会保证指令重排, */ class SingleObjectSyncLazyDouble { private SingleObjectSyncLazyDouble() { } //防止指令重排 private volatile static SingleObjectSyncLazyDouble instance; public static SingleObjectSyncLazyDouble getInstance() { if (instance == null) { //只有并发null的时候进入加锁 synchronized (SingleObjectSyncLazyDouble.class) { //as-if-serial synchronized 只会保证单线程内执行操作结果,指令依然会重排 if (instance == null) { //不加,就会直接创建两个 /*此处会出现指令重排 * instance = new SingleObjectSyncLazyDouble(); * 1、开辟内存 * 2、实例化 * 3、引用指向 * 不加volatile 就会出现混乱效果,导致先引用,这时候第二线程刚好到达第一处检查, * 直接走人了。就出现了大问题 * */ instance = new SingleObjectSyncLazyDouble(); } } } return instance; } }
/** * 静态内部类的使用,静态内部类内部的方法是在第一次调用的时候才会加载,因此可以避免一上来就被初始化的问题 * 也是一种懒加载的形式 */ class SingleObjectStaticLazy { private SingleObjectStaticLazy() { } private static class StaticClass { private static SingleObjectStaticLazy instance = new SingleObjectStaticLazy(); } public static SingleObjectStaticLazy getInstance() { return StaticClass.instance; } }
/** * 枚举 */ public enum SingleObject { INSTANCE; }
结束
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算