电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Java Volatile應用單例模式實現過程解析

瀏覽:43日期:2022-08-21 15:29:08

單例模式

回顧一下,單線程下的單例模式代碼

餓漢式

構造器私有化 自行創建,并且用靜態變量保存static 向外提供這個實例 public 強調這是一個單例,用final

public class sington(){ public final static INSTANCE = new singleton(); private singleton(){}}

第二種:jdk1.5之后用枚舉類型

枚舉類型:表示該類型的對象是有限的幾個

我們可以限定為1個,就稱了單例

public enum Singleto{ INSTANCE}

第三種靜態代碼塊

public class Singleton{public final static INSTANCE;static{ INSTANCE = new Singleton();}private Singleton(){}}

懶漢式構造器私有化

用一個靜態變量保存這個唯一實例

提供一個靜態方法,獲取這個實例

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

public class SingletonDemo { private static SingletonDemo instance = null; private SingletonDemo () { System.out.println(Thread.currentThread().getName() + 't 我是構造方法SingletonDemo'); } public static SingletonDemo getInstance() { if(instance == null) { instance = new SingletonDemo(); } return instance; } public static void main(String[] args) { // 這里的 == 是比較內存地址 System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance()); System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance()); System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance()); System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance()); }}

最后輸出結果:

Java Volatile應用單例模式實現過程解析

但是在多線程的環境下,我們的單例模式是否還是同一個對象了

public class SingletonDemo { private static SingletonDemo instance = null; private SingletonDemo () { System.out.println(Thread.currentThread().getName() + 't 我是構造方法SingletonDemo'); } public static SingletonDemo getInstance() { if(instance == null) { instance = new SingletonDemo(); } return instance; } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> {SingletonDemo.getInstance(); }, String.valueOf(i)).start(); } }}

從下面的結果我們可以看出,我們通過SingletonDemo.getInstance() 獲取到的對象,并不是同一個,而是被下面幾個線程都進行了創建,那么在多線程環境下,單例模式如何保證呢?

Java Volatile應用單例模式實現過程解析

解決方法一

引入synchronized關鍵字

public synchronized static SingletonDemo getInstance() { if(instance == null) { instance = new SingletonDemo(); } return instance;}

輸出結果:

Java Volatile應用單例模式實現過程解析

我們能夠發現,通過引入Synchronized關鍵字,能夠解決高并發環境下的單例模式問題

但是synchronized屬于重量級的同步機制,它只允許一個線程同時訪問獲取實例的方法,但是為了保證數據一致性,而減低了并發性,因此采用的比較少

解決方法二

通過引入DCL Double Check Lock雙端檢鎖機制

public static SingletonDemo getInstance() { if(instance == null) { // 同步代碼段的時候,進行檢測 synchronized (SingletonDemo.class) {if(instance == null) { instance = new SingletonDemo();} } } return instance; }

最后輸出的結果為:

Java Volatile應用單例模式實現過程解析

從輸出結果來看,確實能夠保證單例模式的正確性,但是上面的方法還是存在問題的

DCL(雙端檢鎖)機制不一定是線程安全的,原因是有指令重排的存在,加入volatile可以禁止指令重排

原因是在某一個線程執行到第一次檢測的時候,讀取到 instance 不為null,instance的引用對象可能沒有完成實例化。因為 instance = new SingletonDemo();可以分為以下三步進行完成:

memory = allocate(); // 1、分配對象內存空間 instance(memory); // 2、初始化對象 instance = memory; // 3、設置instance指向剛剛分配的內存地址,此時instance != null

但是我們通過上面的三個步驟,能夠發現,步驟2 和 步驟3之間不存在 數據依賴關系,而且無論重排前 還是重排后,程序的執行結果在單線程中并沒有改變,因此這種重排優化是允許的。

memory = allocate(); // 1、分配對象內存空間 instance = memory; // 3、設置instance指向剛剛分配的內存地址,此時instance != null,但是對象還沒有初始化完成 instance(memory); // 2、初始化對象

這樣就會造成什么問題呢?

也就是當我們執行到重排后的步驟2,試圖獲取instance的時候,會得到null,因為對象的初始化還沒有完成,而是在重排后的步驟3才完成,因此執行單例模式的代碼時候,就會重新在創建一個instance實例

指令重排只會保證串行語義的執行一致性(單線程),但并不會關系多線程間的語義一致性

所以當一條線程訪問instance不為null時,由于instance實例未必已初始化完成,這就造成了線程安全的問題

所以需要引入volatile,來保證出現指令重排的問題,從而保證單例模式的線程安全性

private static volatile SingletonDemo instance = null;

最終代碼

public class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo () { System.out.println(Thread.currentThread().getName() + 't 我是構造方法SingletonDemo'); } public static SingletonDemo getInstance() { if(instance == null) { // a 雙重檢查加鎖多線程情況下會出現某個線程雖然這里已經為空,但是另外一個線程已經執行到d處 synchronized (SingletonDemo.class) //b { //c不加volitale關鍵字的話有可能會出現尚未完全初始化就獲取到的情況。原因是內存模型允許無序寫入if(instance == null) { // d 此時才開始初始化 instance = new SingletonDemo();} } } return instance; } public static void main(String[] args) {// // 這里的 == 是比較內存地址// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance()); for (int i = 0; i < 10; i++) { new Thread(() -> {SingletonDemo.getInstance(); }, String.valueOf(i)).start(); } }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 广州云仓代发-昊哥云仓专业电商仓储托管外包代发货服务 | 学校用栓剂模,玻璃瓶轧盖钳,小型安瓿熔封机,实验室安瓿熔封机-长沙中亚制药设备有限公司 | ?水马注水围挡_塑料注水围挡_防撞桶-常州瑞轩水马注水围挡有限公司 | 非小号行情 - 专业的区块链、数字藏品行情APP、金色财经官网 | 连栋温室大棚建造厂家-智能玻璃温室-薄膜温室_青州市亿诚农业科技 | 涂层测厚仪_光泽度仪_uv能量计_紫外辐照计_太阳膜测试仪_透光率仪-林上科技 | 阻垢剂,反渗透阻垢剂,缓蚀阻垢剂-山东普尼奥水处理科技有限公司 真空粉体取样阀,电动楔式闸阀,电动针型阀-耐苛尔(上海)自动化仪表有限公司 | 专业广州网站建设,微信小程序开发,一物一码和NFC应用开发、物联网、外贸商城、定制系统和APP开发【致茂网络】 | 陕西安闸机-伸缩门-车牌识别-广告道闸——捷申达门业科技 | 盘煤仪,盘料仪,盘点仪,堆料测量仪,便携式激光盘煤仪-中科航宇(北京)自动化工程技术有限公司 | 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 私人别墅家庭影院系统_家庭影院音响_家庭影院装修设计公司-邦牛影音 | 三效蒸发器_多效蒸发器价格_四效三效蒸发器厂家-青岛康景辉 | 众品地板网-地板品牌招商_地板装修设计_地板门户的首选网络媒体。 | 南京精锋制刀有限公司-纵剪机刀片_滚剪机刀片_合金刀片厂家 | 校服厂家,英伦校服定做工厂,园服生产定制厂商-东莞市艾咪天使校服 | 爆炸冲击传感器-无线遥测传感器-航天星百科 | 道康宁消泡剂-瓦克-大川进口消泡剂供应商 | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | 动物解剖台-成蚊接触筒-标本工具箱-负压实验台-北京哲成科技有限公司 | 手持气象站_便携式气象站_农业气象站_负氧离子监测站-山东万象环境 | 5L旋转蒸发器-20L-50L旋转蒸发器-上海越众仪器设备有限公司 | 缓蚀除垢剂_循环水阻垢剂_反渗透锅炉阻垢剂_有机硫化物-郑州威大水处理材料有限公司 | 德州网站制作 - 网站建设设计 - seo排名优化 -「两山建站」 | 中式装修设计_室内中式装修_【云臻轩】中式设计机构 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 泰国专线_泰国物流专线_广州到泰国物流公司-泰廊曼国际 | 周易算网-八字测算网 - 周易算网-宝宝起名取名测名字周易八字测算网 | 猪I型/II型胶原-五克隆合剂-细胞冻存培养基-北京博蕾德科技发展有限公司 | 洗地机_全自动洗地机_手推式洗地机【上海滢皓环保】 | 报警器_家用防盗报警器_烟雾报警器_燃气报警器_防盗报警系统厂家-深圳市刻锐智能科技有限公司 | 高光谱相机-近红外高光谱相机厂家-高光谱成像仪-SINESPEC 赛斯拜克 | 球磨机 选矿球磨机 棒磨机 浮选机 分级机 选矿设备厂家 | 荣事达手推洗地机_洗地机厂家_驾驶式扫地机_工业清洁设备 | 南溪在线-南溪招聘找工作、找房子、找对象,南溪综合生活信息门户! | 电动卫生级调节阀,电动防爆球阀,电动软密封蝶阀,气动高压球阀,气动对夹蝶阀,气动V型调节球阀-上海川沪阀门有限公司 | 昆山PCB加工_SMT贴片_PCB抄板_线路板焊接加工-昆山腾宸电子科技有限公司 | 桐城新闻网—桐城市融媒体中心主办 | 胶辊硫化罐_胶鞋硫化罐_硫化罐厂家-山东鑫泰鑫智能装备有限公司 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 帽子厂家_帽子工厂_帽子定做_义乌帽厂_帽厂_制帽厂_帽子厂_浙江高普制帽厂 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 |