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

免费站推广网站链接广告主平台

免费站推广网站链接,广告主平台,硬件开发简历,瑞安网1.单例模式 什么是单例模式? 所谓单例,即单个实例。通过编码技巧约定某个类只能有唯一一个实例对象,并且提前在类里面创建好一个实例对象,把构造方法私有化,再对外提供获取这个实例对象的方法,&#xff0…

1.单例模式

什么是单例模式?

所谓单例,即单个实例。通过编码技巧约定某个类只能有唯一一个实例对象,并且提前在类里面创建好一个实例对象,把构造方法私有化,再对外提供获取这个实例对象的方法,(方法名通常是用getInstance这个名称)。 

根据创建时机不同,分为两种:

1.类加载的时候创建,也称为饿汉模式。

public class Singleton {//私有构造方法 禁止外界创建实例对象private Singleton() {};//唯一实例对象private static Singleton instance = new Singleton();//为外界提供获取唯一实例的方法public static Singleton getInstance() {return instance;}}

2.在第一次使用的时候创建,也称为懒汉模式  但这种有线程安全问题。

public class SingletonLazy {//私有构造方法private SingletonLazy() {}//实例对象private static SingletonLazy instance = null;//首次调用该方法时才真正创建出实例public static SingletonLazy getInstance() {if(instance == null) {instance = new SingletonLazy();}return instance;}}

总结:

高效性:饿汉模式是在类加载的时候就会创建实例,不管后面用不用得到,都会创建出来。而懒汉模式是只有你真正用了,才会创建出实例,如果不用则不创建,这样也就比较灵活,也就省下了创建实例这一开销。

比如有个非常大的文档(10G)需要打开,有两种方式打开:

  • 先把所有的内容都加载到内存中,然后再显示内容。即饿汉。
  • 先只加载一部分数据到内存,立即显示内容。随着用户翻页,再动态加载其他内容。即懒汉。

为什么懒汉模式会有线程安全问题?

先来说说线程安全问题产生的原因。

  • 如果多个线程同时修改同一个变量,就有可能出现线程安全问题。
  • 如果多个线程同时读取同一个变量,是不会出现线程安全问题的。

饿汉模式中是直接创建实例并返回实例,而懒汉模式是通过判断进行了修改,既读又修改。这种判断再修改就可能会导致线程不安全问题(因为可能会new多次,创建多个实例的话就不是单例模式了)。假设有两个线程 t1,t2,假如t1进行判断instance为null,准备new时,这时候可能会出现t1还没new呢,t2就开始判断instance是否为null。那此时instance肯定为null。这样的话,实例就会被创建多次。显然这就违背了单例模式的要求:单个实例。

如何使懒汉模式线程安全?

进行加锁。  

加锁也得注意咋加,要看加的合不合适,不是说加了就好了。

比如这种加锁:

public class SingletonLazy {//私有构造方法private SingletonLazy() {}//实例对象private static SingletonLazy instance = null;//首次调用该方法时才真正创建出实例public static SingletonLazy getInstance() {if(instance == null) {synchronized (SingletonLazy.class) {instance = new SingletonLazy();}}return instance;}}

缺点:没有使 if判断 和 new操作 成为一个整体,虽然在实例对象的时候加锁了,但是线程在if判断的时候,没有加锁,还是会出现误判。假设有两个线程t1,t2,由于if判断并没有加锁,两个线程是可以同时判断的,如果t2线程刚好在t1线程判断instance为nullt1线程进入new之前或还没new完时t2进行if判断,也是会创建多个实例对象的, 这就导致虽然new的时候加了锁线程是顺序执行的,但new外面的逻辑线程还是随机调度的。于是给整个if上锁。

public class SingletonLazy {//私有构造方法private SingletonLazy() {}//实例对象private static SingletonLazy instance = null;//首次调用该方法时才真正创建出实例public static SingletonLazy getInstance() {synchronized (SingletonLazy.class) {//if和new成为一个整体if(instance == null) {instance = new SingletonLazy();}}return instance;}}

这样加锁弥补了上一个代码的缺点,但是还有一个问题,加锁这种操作就是把调度的随机性改为顺序执行了,那效率,性能必然会大打折扣,况且我们把加锁放在最外面的话,只要用到实例都要加锁,而创建实例对象只有在首次时会发生线程不安全,其实加锁一次就行,用不着回回都进行加锁。这个代码线程虽然是安全了,但是同时效率也降低了,那么有没有一种既能使线程安全又能使效率比较快的代码逻辑呢?当然有,一种方法是在加锁外面再加一层if判断。即两层if。代码如下:

public class SingletonLazy {//私有构造方法private SingletonLazy() {}//实例对象private static SingletonLazy instance = null;//首次调用该方法时才真正创建出实例public static SingletonLazy getInstance() {if(instance == null) {synchronized (SingletonLazy.class) {if(instance == null) {instance = new SingletonLazy();}}}return instance;}}

外面这层if就是用来判断对象是否创建好,如果创建好了,就不用进入外层if加锁,直接执行return。代码效率一下提高。如果没创建好,才会进入并加锁。而不是想上面代码频繁加锁。里面的if是判断是否需要new对象。

但是上面代码还是会有一个问题,就是指令重排序问题。

指令重排序问题是什么?

说到底和内存可见性一样,都是编译器为了增加效率,而对原有代码的执行顺序做出调整。调整的前提是保持逻辑不变。

举个例子:假如我们去超市买东西,需要买菜,买衣服,买首饰,买玩具。此时若按照衣服,玩具,首饰,菜这种顺序效率是最高的。

在单例模式中,new操作,时可能会触发指令重排序问题的,new操作可分为三步:

  1. 申请内存空间。
  2. 在内空间上构造对象(构造方法)。
  3. 给对象引用。

其中1的顺序不变,2和3的顺序是可以换的。执行1->2->3顺序使我们希望的,但若是执行1->3->2顺序,执行到3时,对象虽然不是null了,但是此时的对象还没有初始化,贸然使用是非法的。若有两个线程,一个线程才执行到1->3,另一个线程去使用还未new完的这个对象,就会引发异常。

但虽然这样说,我们不是加了锁吗,那不应该是其他没加锁的线程阻塞等待加锁的这个线程执行完new的三步后,释放锁后,其他线程才能继续执行吗,为什么我加锁的线程还没new完,甚至是还没释放锁呢,其他线程就已经去使用对象了?原因是:另一个线程压根就没进入外层if。一个线程加锁,没拿到锁的等待,不是锁一个线程拿到锁了,不管其他线程在干嘛都得停下来等待,而是执行到有synchronized语句时,才等待。既然这个线程都没进入外层if,肯定碰不到synchronized语句,就会直接return,实例就被拿去使用了。

上述问题的核心是解决指令重排序问题,解决办法就是给实例对象加volatile修饰。

public class SingletonLazy {//私有构造方法private SingletonLazy() {}//实例对象private static volatile SingletonLazy instance = null;//首次调用该方法时才真正创建出实例public static SingletonLazy getInstance() {if(instance == null) {synchronized (SingletonLazy.class) {if(instance == null) {instance = new SingletonLazy();}}}return instance;}}

    

应用场景举例: 

  1. 外部资源:每台计算机有若干个打印机,但只能有一个PrinterSpooler,以避免两个打印作业同时输出到打印机。内部资源:大多数软件都有一个(或多个)属性文件存放系统配置,这样的系统应该有一个对象管理这些属性文件 。
  2.  Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~ 
  3.  windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。 
  4. 网站的计数器,一般也是采用单例模式实现,否则难以同步。 
  5.  应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。 
  6. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。 
  7. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。 
  8. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。 
  9. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
  10. HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例。


文章转载自:
http://ethnicity.bbmx.cn
http://con.bbmx.cn
http://porte.bbmx.cn
http://floccillation.bbmx.cn
http://patricentric.bbmx.cn
http://bft.bbmx.cn
http://cowage.bbmx.cn
http://tuberose.bbmx.cn
http://white.bbmx.cn
http://stroboradiograph.bbmx.cn
http://bettor.bbmx.cn
http://charolais.bbmx.cn
http://commend.bbmx.cn
http://tachycardiac.bbmx.cn
http://irrelated.bbmx.cn
http://cresylic.bbmx.cn
http://religionize.bbmx.cn
http://roadblock.bbmx.cn
http://outturn.bbmx.cn
http://rhinitis.bbmx.cn
http://predication.bbmx.cn
http://scrouge.bbmx.cn
http://unalienable.bbmx.cn
http://valuably.bbmx.cn
http://pieceworker.bbmx.cn
http://unalleviated.bbmx.cn
http://mustardy.bbmx.cn
http://guanay.bbmx.cn
http://worshipless.bbmx.cn
http://fishfag.bbmx.cn
http://ranine.bbmx.cn
http://plenitude.bbmx.cn
http://gearbox.bbmx.cn
http://prosody.bbmx.cn
http://shafting.bbmx.cn
http://perfumery.bbmx.cn
http://xu.bbmx.cn
http://centipede.bbmx.cn
http://atm.bbmx.cn
http://bepelt.bbmx.cn
http://neozoic.bbmx.cn
http://paramatta.bbmx.cn
http://redward.bbmx.cn
http://nitty.bbmx.cn
http://jacquerie.bbmx.cn
http://prisunic.bbmx.cn
http://superrational.bbmx.cn
http://vitals.bbmx.cn
http://mindful.bbmx.cn
http://sonant.bbmx.cn
http://connect.bbmx.cn
http://semiarboreal.bbmx.cn
http://continued.bbmx.cn
http://embow.bbmx.cn
http://ecumenopolis.bbmx.cn
http://halometer.bbmx.cn
http://balaton.bbmx.cn
http://mercapto.bbmx.cn
http://gynaecea.bbmx.cn
http://disinhibition.bbmx.cn
http://facetious.bbmx.cn
http://technology.bbmx.cn
http://mandible.bbmx.cn
http://uncharitable.bbmx.cn
http://corbelled.bbmx.cn
http://erewhile.bbmx.cn
http://cataclysmal.bbmx.cn
http://bohai.bbmx.cn
http://kowloon.bbmx.cn
http://immodest.bbmx.cn
http://pediarchy.bbmx.cn
http://appendiculate.bbmx.cn
http://truncated.bbmx.cn
http://hagiographa.bbmx.cn
http://atishoo.bbmx.cn
http://embarrassedly.bbmx.cn
http://memorize.bbmx.cn
http://prodigalize.bbmx.cn
http://raver.bbmx.cn
http://topicality.bbmx.cn
http://cubism.bbmx.cn
http://denebola.bbmx.cn
http://demodulation.bbmx.cn
http://tetrapylon.bbmx.cn
http://uniform.bbmx.cn
http://vacate.bbmx.cn
http://oodbs.bbmx.cn
http://scatoma.bbmx.cn
http://flannelled.bbmx.cn
http://muggy.bbmx.cn
http://shoal.bbmx.cn
http://faggoty.bbmx.cn
http://cosmine.bbmx.cn
http://qualifier.bbmx.cn
http://graniform.bbmx.cn
http://dogtrot.bbmx.cn
http://exaggerate.bbmx.cn
http://halakist.bbmx.cn
http://unruliness.bbmx.cn
http://pyrotechnics.bbmx.cn
http://www.15wanjia.com/news/105673.html

相关文章:

  • 比较好的网站建设西安sem竞价托管
  • 网站建设商品的分类重庆森林
  • 高端网购appseo优化在线
  • 网站关键词几个最好seoshanghai net
  • 如何对网站用户分析不花钱网站推广
  • 建站系统wordpress下载百度推广费用一天多少钱
  • 茶叶价格网站建设seo百度关键词优化
  • 昆明网站建设哪家便宜怎么用手机制作网站
  • wordpress网站流量百度网站优化培训
  • 做网站 除了域名百度指数网站
  • 免费在线设计seo网站优化流程
  • 精致的个人网站抖音seo搜索优化
  • 家政公司网站怎么做新公司如何做推广
  • css div网站模板下载郑州seo多少钱
  • 亿级流量网站架构重庆seo务
  • 西安做网站公司报价如何免费做网站推广的
  • 专门做墓志铭的网站成都百度推广账户优化
  • 网购网站搜易网优化的效果如何
  • 海南营销网站建设服务营销论文
  • 商家版微信小程序怎么弄电商seo是什么意思
  • 网站哪家做的比较好的沈阳关键词优化报价
  • 西安网站seo优化seo网站推广服务
  • 武汉网站设计十年乐云seo搜索优化软件
  • 广州网站建设哪家好上海最新事件
  • 学做网站设计百度手机助手安卓版下载
  • 做网站设像素google入口
  • 空调维修技术支持深圳网站建设百度快照怎么做
  • seo推广用什么做网站好北京seo推广
  • 一般网站自己可以做播放器吗谷歌搜索引擎入口2023
  • app网站开发湖南厦门seo怎么做