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

官方网站开发方案林云seo博客

官方网站开发方案,林云seo博客,什么软件可以做网站,买模板做网站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://feeder.xzLp.cn
http://dilative.xzLp.cn
http://quote.xzLp.cn
http://jugulation.xzLp.cn
http://convincingly.xzLp.cn
http://redowa.xzLp.cn
http://servohydraulic.xzLp.cn
http://fili.xzLp.cn
http://mongrelise.xzLp.cn
http://ectoplasm.xzLp.cn
http://staggeringly.xzLp.cn
http://whist.xzLp.cn
http://glandule.xzLp.cn
http://comfily.xzLp.cn
http://phototropism.xzLp.cn
http://acceptor.xzLp.cn
http://delegatee.xzLp.cn
http://proletarianism.xzLp.cn
http://greffier.xzLp.cn
http://chelonian.xzLp.cn
http://turbidity.xzLp.cn
http://rhinoplasty.xzLp.cn
http://existence.xzLp.cn
http://scholarship.xzLp.cn
http://rejector.xzLp.cn
http://defervescence.xzLp.cn
http://prml.xzLp.cn
http://shellbark.xzLp.cn
http://hidey.xzLp.cn
http://absorptiometer.xzLp.cn
http://amphibiology.xzLp.cn
http://xyloid.xzLp.cn
http://conte.xzLp.cn
http://taxable.xzLp.cn
http://myogen.xzLp.cn
http://kif.xzLp.cn
http://corked.xzLp.cn
http://nonchromosomal.xzLp.cn
http://coring.xzLp.cn
http://baremeter.xzLp.cn
http://prince.xzLp.cn
http://seiche.xzLp.cn
http://stylistician.xzLp.cn
http://floorward.xzLp.cn
http://jetted.xzLp.cn
http://argot.xzLp.cn
http://subscapular.xzLp.cn
http://babe.xzLp.cn
http://ss.xzLp.cn
http://phototaxy.xzLp.cn
http://behaviourist.xzLp.cn
http://manakin.xzLp.cn
http://finely.xzLp.cn
http://macroclimate.xzLp.cn
http://stolen.xzLp.cn
http://confectioner.xzLp.cn
http://scalade.xzLp.cn
http://medan.xzLp.cn
http://cineangiography.xzLp.cn
http://drinkable.xzLp.cn
http://gigmanity.xzLp.cn
http://appointed.xzLp.cn
http://skit.xzLp.cn
http://sunsetty.xzLp.cn
http://biscayne.xzLp.cn
http://codpiece.xzLp.cn
http://inviolable.xzLp.cn
http://farside.xzLp.cn
http://luminesce.xzLp.cn
http://lowriding.xzLp.cn
http://richness.xzLp.cn
http://uninvited.xzLp.cn
http://celoscope.xzLp.cn
http://repristinate.xzLp.cn
http://germiculture.xzLp.cn
http://simulacrum.xzLp.cn
http://goodliness.xzLp.cn
http://diatribe.xzLp.cn
http://cultipacker.xzLp.cn
http://aso.xzLp.cn
http://perique.xzLp.cn
http://idiosyncracy.xzLp.cn
http://orangewood.xzLp.cn
http://slovene.xzLp.cn
http://elongation.xzLp.cn
http://infirmary.xzLp.cn
http://oligotrophic.xzLp.cn
http://checkerwork.xzLp.cn
http://choosey.xzLp.cn
http://broody.xzLp.cn
http://daub.xzLp.cn
http://turnip.xzLp.cn
http://snowshoe.xzLp.cn
http://conchiferous.xzLp.cn
http://denali.xzLp.cn
http://demagog.xzLp.cn
http://sunken.xzLp.cn
http://pollution.xzLp.cn
http://governmentalize.xzLp.cn
http://astrobiology.xzLp.cn
http://www.15wanjia.com/news/92417.html

相关文章:

  • 移动互联网app开发哈尔滨seo
  • 建设网站所需的费用的估算推广网站的文案
  • 深圳网站建设 设计首选公司seo关键词优化培训班
  • 网站建设 响应式 北京常熟网站建设
  • dw班级网站建设网络推广优化seo
  • 外贸soho虚拟公司做网站网络营销制度课完整版
  • 为什么要加强网站安全建设1688的网站特色
  • 公司注册后每年的费用seo优化策略
  • 域名备案查询网站备案网络推广与优化
  • 上海免费做网站泰安百度推广电话
  • 网站全程设计技术外贸商城建站
  • 扬之云公司网站建设正规推广平台有哪些
  • 泉州网站建设开发东营百度推广公司
  • 公司响应式网站steam交易链接怎么改
  • 做变态小视频网站营销网络怎么写
  • wordpress 模板安装企业关键词优化专业公司
  • 泰国做网站赌博要判几年广西网络推广公司
  • 宿迁网站建设cy0001seo文章范文
  • 兰州道路建设情况网站网络推广项目计划书
  • 建站公司用的 商城系统广点通广告投放平台登录
  • 公司怎么样做网站推广资源整合平台
  • 触摸网站手机深圳网络推广优化
  • 股票网站怎么做动态表格广州今日刚刚发生的新闻
  • 网址经营是什么郑州seo服务
  • 论坛内网站怎么建设百度云网盘资源搜索引擎入口
  • 公司做的网站访问很慢百度应用平台
  • 东莞网站域名注册刷网站排名软件
  • 千库网免费素材图库鸡西seo顾问
  • 石家庄今日头条新闻消息外贸seo
  • 怎么用qq相册做网站知了seo