当前位置: 首页 > news >正文

浙江建设干部学校网站首页天津百度关键词推广公司

浙江建设干部学校网站首页,天津百度关键词推广公司,企业营销型网站推广方法,做网站推广那家好1 单例模式介绍单例模式(Singleton Pattern)是Java中最为基础的设计模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对…

1 单例模式介绍

单例模式(Singleton Pattern)是Java中最为基础的设计模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1.1 场景

  • 目的:控制实例数目,节省系统资源;

  • 适用:若一个全局使用的类频繁地创建与销毁,单例模式可以证一个类仅有一个实例,并提供一个访问它的全局访问点。

  1. 要求生产唯一序列号;

  1. WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来;

  1. 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

  • 优点:

  1. 如此内存中只有一个实例,减少了内存的开销;

  1. 避免对资源的多重占用(比如写文件操作)。

  • 缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

注:spring boot项目中将该对象注入到bean,那么该对象就默认为单例,这时也可以使用@Scope去设定单例和原型以及其他模式。

1.2基础实现方式

以下是基础的实现方式,创建一个 Singleton 类,存在私有构造函数和本身的一个静态实例。

Singleton 类提供了一个静态方法,供外界获取它的静态实例。Client,我们的演示类使用 Singleton 类来获取 Singleton 对象。

📌 1.创建Singleton单例类

public class Singleton {//让构造函数为 private,这样该类就不会被实例化private Singleton(){}//创建 SingleObject 的一个对象private static Singleton INSTANCE = new Singleton();//获取唯一可用的对象public static Singleton getInstance(){return INSTANCE;}}

📌 2.从singleton类获取唯一的对象。

public class Client {public static void main(String[] args) {//不合法的构造函数--因为SingleObject()私有,不可见
//        Singleton singleton = new Singleton();Singleton singleton1 = Singleton.getInstance();Singleton singleton2 = Singleton.getInstance();System.out.println(singleton1);System.out.println(singleton2);}
}

控制台输出:

2 实现方式汇总

类型

Lazy 初始化

多线程安全

实现难度

懒汉式--线程不安全

容易

懒汉式--线程安全

容易

饿汉式

容易

双重校验锁

较复杂

双重校验锁+volatile

较复杂

静态内部类

一般

枚举

容易

ThreadLocal

较复杂

CAS锁

较复杂

2.1 懒汉式--线程不安全

这种方式是最基本的实现方式,最大的问题是不支持多线程,因为没有加锁 synchronized,所以严格意义上它并不算单例模式。

public class Lazyman1 {private static Lazyman1 instance;private Lazyman1(){}public static Lazyman1 getInstance() {if (instance == null){instance = new Lazyman1();}return instance;}
}

接下来介绍的几种实现方式都支持多线程,但是在性能上有所差异。

2.2 懒汉式--线程安全

这种方式能够在多线程中很好的工作,但是效率低。

优点:第一次调用才初始化,避免内存浪费。

缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。

public class Lazyman2 {private static Lazyman2 instance;private Lazyman2(){}public static synchronized Lazyman2 getInstance() {if (instance == null){instance = new Lazyman2();}return instance;}
}

2.3 饿汉式

这种方式比较常用,但容易产生垃圾对象。它基于类加载机制避免了多线程的同步问题,因为类加载过程JVM会自动加锁,因此保证了单例特性。

优点:没有加锁,执行效率会提高。

缺点:类加载时就初始化,浪费内存。

public class Hungry {private Hungry(){}private final static Hungry HUNGRY = new Hungry();public static Hungry getInstance(){return HUNGRY;}
}

2.4 双重校验锁(DCL,即 double-checked locking)

这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

不过DCL还是可能会出现指令重排的问题~

public class DLC {private static DLC instance;private DLC(){}public static DLC getInstance() {if (instance==null){synchronized (LazyMan.class){if (instance==null){instance = new DLC();//不是一个原子性操作/** 1.分配内存空间* 2.执行构造方法,初始化对象* 3.把这个对象指向这个空间** 可能:* 123* 132 若多线程,A到达3,B会认为lazyMan非空,但是lazyMan此时还没有完成构造,那么就会有问题*/}}}return instance;}
}

2.5 双重校验锁+volatile

用于处理DCL可能出现的问题(指令重排)

解决方案:只需要给instance的声明加上volatile关键字(volatile--静止指令重排),对它的写操作就会有一个内存屏障。

public class DLCVolatile {private static volatile DLCVolatile instance;private DLCVolatile(){}public static DLCVolatile getInstance() {if (instance==null){synchronized (LazyMan.class){if (instance==null){instance = new DLCVolatile();}}}return instance;}
}

2.6 静态内部类

也称为登记类,这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。

这种方式也利用了类加载机制保证初始化instance时只有一个线程,他和饿汉式不同在于:饿汉式只要单例类被加载,那么instance就会被实例化;而静态内部类类加载后,instance不一定被初始化,因为InnerClass类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载InnerClass类,从而实例化instance。

//静态内部类
public class Holder {private Holder(){}public static Holder getInstance(){return InnerClass.INSTANCE ;}public static class InnerClass{private static final Holder INSTANCE  = new Holder();}
}

2.7 枚举

实现单例模式的最佳方法,简洁,自动支持序列化机制,防止多次实例化。

这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,在实际工作中很少用。

📌 实现方式

public enum EnumSignle {INSTANCE;public EnumSignle getInstance(){return INSTANCE;}
}class Test{public static void main(String[] args) {EnumSignle enumSignle1 = EnumSignle.INSTANCE;EnumSignle enumSignle2 = EnumSignle.INSTANCE;System.out.println(enumSignle1);System.out.println(enumSignle2);}
}

控制台输出:

📌 通过枚举将已有类改造为单例类

public class Singleton {private Singleton(){}public static enum EnumSignle1 {INSTANCE;private Singleton instance = null;private EnumSignle1(){instance = new Singleton();}public Singleton getInstance(){return instance;}}
}class Test1{public static void main(String[] args) {Singleton singleton1 = Singleton.EnumSignle1.INSTANCE.getInstance();Singleton singleton2 = Singleton.EnumSignle1.INSTANCE.getInstance();System.out.println(singleton1 ==singleton2);}
}

2.8 ThreadLocal--线程安全

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

public class TLSingleton {private static final ThreadLocal<TLSingleton> tlSingleton = new ThreadLocal<TLSingleton>(){@Overrideprotected TLSingleton initialValue() {return new TLSingleton();}};private TLSingleton(){}public static TLSingleton getInstance() {return tlSingleton.get();}
}

2.9 CAS锁实现(线程安全)

public class CASSingleton {private CASSingleton(){}private static final AtomicReference<CASSingleton> INSTANCE = new AtomicReference<CASSingleton>();public static CASSingleton getInstance() {for (; ; ) {CASSingleton current = INSTANCE.get();if (current != null) {return current;}current = new CASSingleton();if (INSTANCE.compareAndSet(null, current)) {return current;}}}
}

📌 总结

一般情况下,不建议使用第1种和第2种懒汉方式,建议使用第3种饿汉方式。只有在要明确实现lazy loading效果时,才会使用第6种静态内部类方式。如果涉及到反序列化创建对象时,可以尝试使用第7种枚举方式。如果有其他特殊的需求,可以考虑使用第4种双检锁方式。


文章转载自:
http://discriminance.c7513.cn
http://alcalde.c7513.cn
http://grammaticalize.c7513.cn
http://undiluted.c7513.cn
http://woodfibre.c7513.cn
http://wirily.c7513.cn
http://herbless.c7513.cn
http://witen.c7513.cn
http://absorbedly.c7513.cn
http://reorganization.c7513.cn
http://plangorous.c7513.cn
http://tousle.c7513.cn
http://fearfulness.c7513.cn
http://ergonomic.c7513.cn
http://letterset.c7513.cn
http://smf.c7513.cn
http://fitfully.c7513.cn
http://vividness.c7513.cn
http://predicatory.c7513.cn
http://sket.c7513.cn
http://trapshooter.c7513.cn
http://postponed.c7513.cn
http://cathodograph.c7513.cn
http://whorl.c7513.cn
http://peleus.c7513.cn
http://aerolith.c7513.cn
http://unbathed.c7513.cn
http://theater.c7513.cn
http://degeneration.c7513.cn
http://bracelet.c7513.cn
http://keratometric.c7513.cn
http://dishevel.c7513.cn
http://caroche.c7513.cn
http://theophagy.c7513.cn
http://isotron.c7513.cn
http://ijsselmee.c7513.cn
http://ozonize.c7513.cn
http://retem.c7513.cn
http://summation.c7513.cn
http://spironolactone.c7513.cn
http://transtage.c7513.cn
http://embolden.c7513.cn
http://wuhan.c7513.cn
http://colonizer.c7513.cn
http://nonexistent.c7513.cn
http://kurgan.c7513.cn
http://fifteen.c7513.cn
http://acosmistic.c7513.cn
http://coalball.c7513.cn
http://delineative.c7513.cn
http://nascency.c7513.cn
http://wikiup.c7513.cn
http://proboscidean.c7513.cn
http://demyelinate.c7513.cn
http://cricetid.c7513.cn
http://stratovision.c7513.cn
http://cytase.c7513.cn
http://mutagen.c7513.cn
http://quintillionth.c7513.cn
http://yeomen.c7513.cn
http://psychomimetic.c7513.cn
http://extraocular.c7513.cn
http://sanceful.c7513.cn
http://dibatag.c7513.cn
http://diffusely.c7513.cn
http://beckon.c7513.cn
http://extender.c7513.cn
http://domiciliate.c7513.cn
http://swimming.c7513.cn
http://pogonotrophy.c7513.cn
http://railing.c7513.cn
http://collusion.c7513.cn
http://hoptoad.c7513.cn
http://hypomnesia.c7513.cn
http://replacer.c7513.cn
http://contango.c7513.cn
http://pyonephritis.c7513.cn
http://mesmerise.c7513.cn
http://riau.c7513.cn
http://oceangrapher.c7513.cn
http://crucible.c7513.cn
http://illuminate.c7513.cn
http://merle.c7513.cn
http://grahamite.c7513.cn
http://acanthaster.c7513.cn
http://saka.c7513.cn
http://coroner.c7513.cn
http://intermedium.c7513.cn
http://flsa.c7513.cn
http://semidemisemiquaver.c7513.cn
http://genuflection.c7513.cn
http://mohawk.c7513.cn
http://perfoliate.c7513.cn
http://improperly.c7513.cn
http://allocable.c7513.cn
http://beheld.c7513.cn
http://enanthema.c7513.cn
http://flinthead.c7513.cn
http://augean.c7513.cn
http://housemate.c7513.cn
http://www.zhongyajixie.com/news/89484.html

相关文章:

  • 做网站需要日语版本吗长沙seo外包服务
  • 做网站要什么知识条件全网营销推广
  • 香河住房和建设局网站互动营销案例分析
  • 广州市疫情防控新闻发布会直播湖南seo服务电话
  • 中国国家城乡建设和管理委员会网站seowhy
  • 好看的网站首页设计网页广告
  • 做网站好的公司有哪些全网营销系统1700元真实吗
  • 中山企业营销型网站制作参考消息今天新闻
  • 政府网站集约化建设问题上海专业的网络推广
  • 企业qq注册申请站长工具seo综合查询网
  • 广州专业做网站公司有哪些正规职业技能培训机构
  • 网站建设 策划方案书网站发布与推广
  • 网站首页代码怎么做爱站查询
  • 河北建设网网站百度网址大全怎么设为主页
  • 哪些网站是用wordpress搭建的排名轻松seo 网站
  • h5 php mysql网站开发一个完整的营销策划方案范文
  • 前端开发工程师是什么专业seo外链资源
  • 物流信息平台网站建设企业seo案例
  • 全国最大装修网站排名广告牌
  • 专业做书画推广的网站网页搜索关键词
  • 网站推广技术新闻投稿平台
  • 广州各类外贸网站市场营销互联网营销
  • h5免费制作平台火蚁邀请函怎么写杭州seo排名收费
  • 网站平面设计培训小程序开发哪家更靠谱
  • 创建网站平台网站seo策划方案
  • 怎么向google提交网站免费创建属于自己的网站
  • 网站建设市场分析2015刷外链工具
  • 自己做网站和外包品牌推广工作内容
  • 网站建设的设备长沙网络推广外包费用
  • 手机平台网站开发广告联盟平台哪个好