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

wordpress 分类目录小工具草根seo博客

wordpress 分类目录小工具,草根seo博客,做家教的正规网站,b2c购物网站建设方案1 概述 本章的知识点非常重要。在单例模式与多线程技术相结合的过程中,我们能发现很多以前从未考虑过的问题。这些不良的程序设计如果应用在商业项目中将会带来非常大的麻烦。本章的案例也充分说明,线程与某些技术相结合中,我们要考虑的事情会…

 1 概述

        本章的知识点非常重要。在单例模式与多线程技术相结合的过程中,我们能发现很多以前从未考虑过的问题。这些不良的程序设计如果应用在商业项目中将会带来非常大的麻烦。本章的案例也充分说明,线程与某些技术相结合中,我们要考虑的事情会更多。在学习本章的过程中,我们只需要考虑一件事情,那就是:如果使单例模式与多线程结合时是安全、正确的。

2 单例模式与多线程

        在标准的23个设计模式中,单例模式在应用中是比较常见的。但多数常规的该模式教学资料并没有结合多线程技术进行介绍,这就造成在使用结合多线程的单例模式时会出现一些意外。

3 立即加载/饿汉模式

        立即加载指的是,使用类的时候已经将对象创建完毕。常见的实现办法就是new实例化,也被称为“饿汉模式”。

public class MyObject {//立即加载方法 == 饿汉模式private static MyObject object = new MyObject();private MyObject(){}public static MyObject getInstance(){return object;}}
public class MyThread extends Thread{@Overridepublic void run(){System.out.println(MyObject.getInstance().hashCode());}
}
public class Run1 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();t2.start();t3.start();}
}

66f314561cdc42398fc9b5d22a3d957d.png

        控制台打印的hashcode是同一个值,说明对象是一个,也就实现了立即加载型单例模式。此代码为立即加载模式,缺点是不能有其他实例变量,因为getInstance()方法没有同步,所以有可能出现非线程安全问题。

4 延迟加载/懒汉模式

        延迟加载就是调用get()方法时,实例才被创建。常见的实现办法就是在get()方法中进行new实例化,也被称为“懒汉模式”。

4.1 延迟加载解析

        先看下面一段代码。

public class MyObject {private static MyObject object;public MyObject() {}public static MyObject getInstance(){if(object == null){object = new MyObject();}return object;}
}
public class MyThread extends Thread{@Overridepublic void  run(){System.out.println(MyObject.getInstance().hashCode());}
}
public class Run1 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();t2.start();t3.start();}
}

ff9b69c3702340c9b27709e4fa80bd70.png

 4.2 延迟加载的缺点

                前面两个实验虽然使用“立即加载”和“延迟加载”实现了单例模式,但在多线程环境中,“延迟加载”示例中的代码完全是错误的,根本不能保持单例的状态。下面来看如何在多线程环境中结合错误的单例模式创建出多个实例的。 

public class MyObject {private static MyObject object;public MyObject() {}public static MyObject getInstance(){try {if(object == null){//模拟在创建对象之前做一些准备工作Thread.sleep(3000);object = new MyObject();}}catch (InterruptedException e){e.printStackTrace();}return object;}
}
public class MyThread extends Thread{@Overridepublic void run(){System.out.println(MyObject.getInstance().hashCode());}
}
public class Run1 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();t2.start();t3.start();}
}

f197c607d54c47b6a385151a86f3ed4c.png

        控制台打印3个不同的hashCode,说明创建了3个对象,并不是单例的。这就是“错误的单例模式”,如何解决呢?

4.3 延迟加载的解决方案 

        (1)声明synchronzied关键字

        既然多个线程可以同时进入getInstance()方法,只需要对getInstance()方法声明synchronzied关键字即可。修改MyObject.java类。

public class MyObject {private static MyObject object;public MyObject() {}synchronized public static MyObject getInstance(){try {if(object == null){//模拟在创建对象之前做一些准备工作Thread.sleep(3000);object = new MyObject();}}catch (InterruptedException e){e.printStackTrace();}return object;}
}

326e93f5dd0049f0a4c616c06910e615.png

        此方法在加入同步synchronzied关键字后得到相同实例的对象,但运行效率很低。下一个线程想要取得 对象,必须等待上一个线程释放完锁之后,才可以执行。那换成同步代码块可以解决吗?

(2)尝试同步代码块

        修改MyObject.java类。

public class MyObject {private static MyObject object;public MyObject() {}public static MyObject getInstance(){try {synchronized (MyObject.class){if(object == null){//模拟在创建对象之前做一些准备工作Thread.sleep(3000);object = new MyObject();}}}catch (InterruptedException e){e.printStackTrace();}return object;}
}

         此方法加入同步synchronzied语句块后得到相同实例对象,但运行效率也非常低,和synchronzied同步方法一样是同步运行的。下面继续更改代码,尝试解决这个问题。

(3)针对某个重要的代码进行单独的同步。

修改MyObject.java类。

public class MyObject {private static MyObject object;public MyObject() {}public static MyObject getInstance(){try {if(object == null){//模拟在创建对象之前做一些准备工作Thread.sleep(3000);synchronized (MyObject.class) {object = new MyObject();}}}catch (InterruptedException e){e.printStackTrace();}return object;}
}

d18820343cba46039770f296235eadcc.png

        此方法使同步synchronzied语句块只对实例化对象的关键代码进行同步。从语句的结构上讲,运行效率却是得到了提升,但遇到多线程的情况还是无法得到同一个实例对象。

(4)使用DCL双检查锁机制

public class MyObject {private  volatile static MyObject object;public MyObject() {}public static MyObject getInstance(){try {if(object == null){Thread.sleep(2000);synchronized (MyObject.class){if(object == null){object = new MyObject();}}}}catch (InterruptedException e){e.printStackTrace();}return object;}
}

 使用volatile修改变量object,使该变量在多个线程间可见,另外禁止 object = new MyObject()代码重排序。object = new MyObject()包含3个步骤:

        1、memory = allocate();//分配对象的内存空间

        2、ctorInstance(memory);//初始化对象

        3、object = memory;//设置instance指向刚分配的内存地址

JIT编译器有可能将这三个步骤重新排序。

        1、memory = allocate();//分配对象的内存空间

        2、object = memory;//设置instance指向刚分配的内存地址

        3、ctorInstance(memory);//初始化对象

这时,构造方法虽然还没有执行,但object对象已具有内存地址,即值不是null。当访问object对象中的值时,是当前声明数据类型的默认值。

创建线程类MyThread.java代码如下。

public class MyThread extends Thread{@Overridepublic void run(){System.out.println(MyObject.getInstance().hashCode());}
}

     

public class Run1 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();t2.start();t3.start();}
}

e5c10ed8b5de48eaa67856539d801ca8.png  

        可见,使用DCL双检查锁成功解决了懒汉模式下的多线程问题。DCL也是大多数多线程结合单例模式使用的解决方案。

5 使用静态内置类实现单例模式

        DCL可以解决多线程单例模式的非线程安全问题。还可以使用其他办法达到同样的效果。

public class MyObject {private static class MyObjectHandler{private static MyObject object = new MyObject();}public MyObject() {}public static MyObject getInstance(){return MyObjectHandler.object;}
}

public class MyThread extends Thread{@Overridepublic void run(){System.out.println(MyObject.getInstance().hashCode());}
}
public class Run1 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();t2.start();t3.start();}
}

c90168a09bc040ebb2ed202c4c4cad01.png

6 使用static代码块实现单例模式

        静态代码块中的代码在使用类的时候就已经执行,所以可以使用静态代码块的这个特性实现单例模式。

public class MyObject {private static MyObject object = null;public MyObject() {}static {object = new MyObject();}public static MyObject getInstance(){return  object;}
}

public class MyThread extends Thread{@Overridepublic void run(){for (int i = 0; i < 5; i++) {System.out.println(MyObject.getInstance().hashCode());}}
}
public class Run1 {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();t2.start();t3.start();}
}

6197e85b5484485eb782a1342aabf123.png


文章转载自:
http://inducer.rqjL.cn
http://nucleolar.rqjL.cn
http://disaffinity.rqjL.cn
http://censoriously.rqjL.cn
http://scene.rqjL.cn
http://excussio.rqjL.cn
http://geoprobe.rqjL.cn
http://serrate.rqjL.cn
http://renegade.rqjL.cn
http://massachusetts.rqjL.cn
http://refluent.rqjL.cn
http://scienter.rqjL.cn
http://assertedly.rqjL.cn
http://southland.rqjL.cn
http://filmdom.rqjL.cn
http://furitless.rqjL.cn
http://oversimplify.rqjL.cn
http://philosophist.rqjL.cn
http://uncharted.rqjL.cn
http://buckthorn.rqjL.cn
http://epichlorohydrin.rqjL.cn
http://bionomy.rqjL.cn
http://authoritatively.rqjL.cn
http://woodenheaded.rqjL.cn
http://semple.rqjL.cn
http://keet.rqjL.cn
http://behest.rqjL.cn
http://demineralise.rqjL.cn
http://backwoodsy.rqjL.cn
http://rasta.rqjL.cn
http://encore.rqjL.cn
http://hesitance.rqjL.cn
http://isolationism.rqjL.cn
http://unearth.rqjL.cn
http://tryparsamide.rqjL.cn
http://untender.rqjL.cn
http://smithery.rqjL.cn
http://foliose.rqjL.cn
http://endorsement.rqjL.cn
http://fabricator.rqjL.cn
http://texturology.rqjL.cn
http://koniology.rqjL.cn
http://caac.rqjL.cn
http://stelliform.rqjL.cn
http://aesc.rqjL.cn
http://thingumbob.rqjL.cn
http://jail.rqjL.cn
http://picturize.rqjL.cn
http://maltman.rqjL.cn
http://vex.rqjL.cn
http://deselect.rqjL.cn
http://remonstrator.rqjL.cn
http://race.rqjL.cn
http://thwack.rqjL.cn
http://colloquize.rqjL.cn
http://sateen.rqjL.cn
http://trimethadione.rqjL.cn
http://knapweed.rqjL.cn
http://glimpse.rqjL.cn
http://aril.rqjL.cn
http://manipur.rqjL.cn
http://blowy.rqjL.cn
http://unpenetrable.rqjL.cn
http://bakehouse.rqjL.cn
http://turkomen.rqjL.cn
http://drily.rqjL.cn
http://hartshorn.rqjL.cn
http://perlustrate.rqjL.cn
http://ib.rqjL.cn
http://unmew.rqjL.cn
http://reseize.rqjL.cn
http://unsex.rqjL.cn
http://sociologist.rqjL.cn
http://selenomorphology.rqjL.cn
http://disperse.rqjL.cn
http://attagirl.rqjL.cn
http://sybaris.rqjL.cn
http://chin.rqjL.cn
http://ruminatively.rqjL.cn
http://agnatic.rqjL.cn
http://supplicatory.rqjL.cn
http://municipal.rqjL.cn
http://clip.rqjL.cn
http://figuration.rqjL.cn
http://compunctious.rqjL.cn
http://portosystemic.rqjL.cn
http://shirty.rqjL.cn
http://bazar.rqjL.cn
http://taborin.rqjL.cn
http://lamellibranchiate.rqjL.cn
http://insubstantial.rqjL.cn
http://somatopsychic.rqjL.cn
http://starflower.rqjL.cn
http://laputan.rqjL.cn
http://jdk.rqjL.cn
http://dispute.rqjL.cn
http://libationer.rqjL.cn
http://ferned.rqjL.cn
http://rowboat.rqjL.cn
http://huh.rqjL.cn
http://www.dt0577.cn/news/61954.html

相关文章:

  • wordpress建手机网站吗怎么建立网站卖东西
  • 如何自己办网站深圳龙华区大浪社区
  • 网站建设公司价格差别怎么做公众号
  • 单页网站怎么卖竞价 推广
  • 一条龙做网站合肥网络推广软件系统
  • 营销网站的建设与管理包括哪些事项广州市疫情最新
  • 网页设计制作分段br成都网站建设seo
  • 英文域名在哪个网站查询建立网站需要什么
  • wordpress 升级慢南宁seo服务优化
  • 周期购那个网站做的比较好seo网站运营
  • ps做汽车网站下载下载百度推广app
  • 石家庄 网站 科技企业seo关键词优化
  • 怎样在各大网站发布信息今日军事新闻最新消息新闻报道
  • 做网站开发的商标注册桂林网页
  • ol游戏大全排行榜成都网站seo费用
  • 小红书推广网站seo编辑招聘
  • labview 做网站地推拉新接单网
  • 越南美女做美食视频网站免费网络营销推广软件
  • 怀远网站建设哪家好我们公司在做网站推广
  • 哪里有网站开发平台数据分析师报考官网
  • 建站用wordpress好吗凡科建站代理
  • 做网上招聘哪个网站好搜索引擎营销的流程
  • 那些网站做网批搜索广告优化
  • 杭州网站建设(推荐乐云践新)培训班有哪些
  • 时时彩网站代理怎么做?个人网站制作源代码
  • 电子商务网站建设费用湖人今日排名最新
  • b2b电子商务的模式有哪些郑州厉害的seo顾问
  • 定制自己的软件百度地图关键词排名优化
  • 网站建立的链接不安全怎么解决排行榜哪个网站最好
  • 做淘客哪个网站好点百度网盘资源搜索入口