多例模式

多例:只是單例的一種延伸 ? 不必過于在意各種模式的名字,重要的是學會融會貫通,把生產的car放到集合中 類似JDBC 的連接池 把連接對象放到池中

多例模式特點:
???? 1. 多例類可以有多個實例
???? 2. 多例類必須自己創建自己的實例,并管理自己的實例,和向外界提供自己的實例

package com.pers.hoobey;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Car1 {
  private static Car1 car1 = new Car1();
  private static Car1 car2 = new Car1();
  private static List<Car1> list = new ArrayList<Car1>();//用于存放多個實例的car
  private static final int maxCount =2;//最多的實例數
  static{
    list.add(car1);
    list.add(car2);
  }
  private Car1(){}//私有構造方法 避免外部創建實例
/*
* @description 指定拿取某一個實例
*/
  public static Car1 getInstance(int index){
    return list.get(index);
  }
  //隨機拿取實例
  public static Car1 getInstance(){
    Random random = new Random();
    int current = random.nextInt(maxCount);
    return list.get(current);
}
public void run(){
System.out.println("奔跑中的車.....");
}
}

順便總結一下 普通工廠模式 工廠方法模式和抽象工廠模式的區別:

簡單工廠是用來生產”東西“的,那任何”東西“的子類,比如汽車,自行車,輪船,洗發水都是可以被生產的,但此處簡單工廠的壓力太大了啊,任何”東西“的子類都可以被生產,負擔太重,所以一般對簡單工廠類也有種稱呼,叫”上帝類“。
而工廠方法模式就很好的減輕了工廠類的負擔,把某一類/某一種東西交由一個工廠生產,同時增加某一類”東西“并不需要修改工廠類,只需要添加生產這類”東西“的工廠即可,使得工廠類符合開放-封閉原則。
對于”東西“的分類,有時候不能光是橫向的分類,從另一個角度也是可以分類的,不知道這句話的意思能不能懂,打個比方:汽車可以根據品牌分為奔馳、奧迪,也可以根據類別分為普通三廂車和SUV車,如果用工廠方法來描述的話,奔馳車工廠有一個方法即生產奔馳車,奧迪車工廠有一個方法生產奧迪車,但在有多重分類的情形下,這樣寫已經不夠用,不符合實際了,這個時候需要用到抽象工廠模式,即奧迪車工廠有兩個方法,一個方法是生產普通三廂奧迪車,另一個方法是生產SUV奧迪車。奔馳車工廠有兩個方法,一個方法是生產普通三廂奔馳車,另一個方法是生產SUV奔馳車。
上面即工廠方法模式和抽象工廠模式的應用場景,因為這兩者很像,所以概念上不容易區分,可以這么說,工廠方法模式是一種極端情況的抽象工廠模式,而抽象工廠模式可以看成是工廠方法模式的一種推廣。

再說下抽象工廠模式,此處的抽象工廠接口應該是有兩個方法,一個是生成普通三廂車,一個是生產SUV車,可以說,生產的”東西“已經被限定住了,因此你不能生產某品牌汽車外的其他”東西“,因而可以理解成使用抽象工廠模式不能新增新的”東西“(在簡單工廠和工廠方法中理論上都是可以新增任意”東西“的)

?

下面分析一下懶漢模式下的單例模式

作為一個單例,我們首先要確保的就是實例的“唯一性”,有很多因素會導致“唯一性”失效,它們包括:多線程、序列化、反射、克隆等,更特殊一點的情況還有:分布式系統、多個類加載器等等。其中,多線程問題最為突出。為了提高應用的工作效率,現如今我們的工程中基本上都會用到多線程;目前使用單線程能輕松完成的任務,日復一日,隨著業務邏輯的復雜化、用戶數量的遞增,也有可能要被升級為多線程處理。所以任何在多線程下不能保證單個實例的單例模式,我都認為應該立即被棄用。

在只考慮一個類加載器的情況下,“餓漢方式”實現的單例(在系統運行起來裝載類的時候就進行初始化實例的操作,由JVM虛擬機來保證一個類的初始化方法在多線程環境中被正確加鎖和同步,所以)是線程安全的,而“懶漢”方式則需要注意了,先來看一種最簡單的“懶漢方式”的單例:

這種寫法只能在單線程下使用。如果是多線程,可能發生一個線程通過并進入了?if (singleton == null)?判斷語句塊,但還未來得及創建新的實例時,另一個線程也通過了這個判斷語句,兩個線程最終都進行了創建,導致多個實例的產生。所以在多線程環境下必須摒棄此方式。

除了多并發的情況,實現單例模式時另一個重要的考量因素是效率。前述的“懶漢方式”的多線程問題可以通過加上?synchronized?修飾符解決,但考慮到性能,一定不要簡單粗暴地將其添加在如下位置:

上述方式通過為?getInstence()?方法增加?synchronized?關鍵字,迫使每個線程在進入這個方法前,要先等候別的線程離開該方法,即不會有兩個線程可以同時進入此方法執行?new Singleton(),從而保證了單例的有效。但它的致命缺陷是效率太低了,每個線程每次執行?getInstance()?方法獲取類的實例時,都會進行同步。而事實上實例創建完成后,同步就變為不必要的開銷了,這樣做在高并發下必然會拖垮性能。所以此方法雖然可行但也不推薦。那我們將同步方法改為同步代碼塊是不是就能減少同步對性能的影響了呢:

但是這種同步卻并不能做到線程安全,同最初的懶漢模式一個道理,它可能產生多個實例,所以亦不可行。我們必須再增加一個單例不為空的判斷來確保線程安全,也就是所謂的“雙重檢查鎖定”(Double Check Lock(DCL))方式:

此方法的“Double-Check”體現在進行了兩次?if (singleton == null)?的檢查,這樣既同步代碼塊保證了線程安全,同時實例化的代碼也只會執行一次,實例化后同步操作不會再被執行,從而效率提升很多(詳細比較見附錄 1)。

雙重檢查鎖定(DCL)方式也是延遲加載的,它唯一的問題是,由于Java 編譯器允許處理器亂序執行,在JDK版本小于1.5時會有DCL失效的問題(原因解釋詳見附錄 2)。當然,現在大家使用的JDK普遍都已超過1.4,只要在定義單例時加上1.5及以上版本具體化了的volatile關鍵字,即可保證執行的順序,從而使單例起效。所以 DCL 方式是推薦的一種方式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541757.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541757.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541757.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Oracle public view,【易錯概念】以太坊Solidity函數的external/internal,public/private,view/pure/payable區別...

1. 函數類型&#xff1a;內部(internal)函數和外部(external)函數函數類型是一種表示函數的類型。可以將一個函數賦值給另一個函數類型的變量&#xff0c;也可以將一個函數作為參數進行傳遞&#xff0c;還能在函數調用中返回函數類型變量。 函數類型有兩類&#xff1a;- 內部(i…

c-style字符字符串_C字符串-能力問題與解答

c-style字符字符串C programming String Aptitude Questions and Answers: In this section you will find C Aptitude Questions and Answers on Strings, String is the set of characters and String related Aptitude Questions and Answers you will find here. C編程Stri…

PHP Smarty template for website

/******************************************************************************* PHP Smarty template for website* 說明&#xff1a;* 之前一直在想將MVC的方式加在PHP做的網站上&#xff0c;這樣比較好處理&#xff0c;相對來說比較好* 處理…

ftp連接oracle服務器,使用SSL加密連接FTP - 架建SSL安全加密的FTP服務器(圖)_服務器應用_Linux公社-Linux系統門戶網站...

四、使用SSL加密連接FTP啟用Serv-U服務器的SSL功能后&#xff0c;就可以利用此功能安全傳輸數據了&#xff0c;但FTP客戶端程序必須支持SSL功能才行。 如果我們直接使用IE瀏覽器進行登錄則會出現圖4顯示的錯誤信息&#xff0c;一方面是以為沒有修改默認的端口21為990&#xff0…

c# 情感傾向_C否則-能力傾向問題與解答

c# 情感傾向C programming if else Aptitude Questions and Answers: In this section you will find C Aptitude Questions and Answers on condition statements – if else, nested if else, ladder if else, conditional operators etc. C語言編程如果有問題&#xff0c;請…

springboot中使用緩存shiro-ehcache

在pom.xml中注入緩存依賴&#xff0c;版本(Sep 09, 2016)spring-context-support 包含支持UI模版&#xff08;Velocity&#xff0c;FreeMarker&#xff0c;JasperReports&#xff09;&#xff0c; 郵件服務&#xff0c; 腳本服務(JRuby)&#xff0c; 緩存Cache&#xff08;EHCa…

oracle 微信公眾號,關于微信公眾號貼代碼的方法

微信公眾號碼上貼代碼一直一來都是個頭疼的問題。吐槽一句&#xff1a;要是后臺編輯器支持markdown就好了。今天教大家用在線markdown排版工具&#xff0c;把代碼完美貼到微信公眾號上。長話短說&#xff0c;今天用到的兩個工具&#xff1a;首先&#xff0c;以一段代碼為例。假…

計算理論 形式語言與自動機_下推式自動機(PDA)| 計算理論

計算理論 形式語言與自動機Pushdown Automaton (PDA) is a kind of Automaton which comes under the theory of Computation that appoints stack. The word Pushdown stands due to the fact that the stack can be pushed down as operations can only work on the elements…

運維人員究竟如何提升價值,持續獲得高薪?

作者簡介&#xff1a;老男孩&#xff0c;北京老男孩IT教育創始人&#xff0c;17年IT經驗&#xff0c;資深Linux實戰專家&#xff0c;IT培訓界實戰派頂尖大師&#xff0c;國內將實戰心理學體系大量注入IT運維培訓領域的第一人&#xff0c;多本IT暢銷圖書作者&#xff0c;51CTO金…

Webservice soap wsdl區別之個人見解

Web Service實現業務訴求&#xff1a;Web Service是真正“辦事”的那個&#xff0c;提供一種辦事接口的統稱。WSDL提供“能辦的事的文檔說明”&#xff1a;對要提供的服務的一種描述格式。我想幫你的忙&#xff0c;但是我要告訴你我都能干什么&#xff0c;以及干這些事情需要的…

java uuid靜態方法_Java UUID nameUUIDFromBytes()方法及示例

java uuid靜態方法UUID類名UUIDFromBytes()方法 (UUID Class nameUUIDFromBytes() method) nameUUIDFromBytes() method is available in java.util package. java.util包中提供了nameUUIDFromBytes()方法 。 nameUUIDFromBytes() method is used to get a UUID constructed fr…

清空 linux 服務器,Linux服務器清理

Why?廢話不多說直接來圖&#xff0c;可以看出磁盤已經快要滿了未清之前What?可以看出mnt文件夾占用的最大&#xff0c;然后進入mnt目錄里通過命令,根據文件大小對該路徑下文件排序du -h --max-depth1我們服務器出現磁盤快滿了的原因是因為&#xff0c;服務器部署了多個tomcat…

Git中的AutoCRLF與SafeCRLF換行符問題

2019獨角獸企業重金招聘Python工程師標準>>> 原文&#xff1a;http://www.cnblogs.com/flying_bat/archive/2013/09/16/3324769.html 最近在使用GitHub&#xff0c;發現不時沒有修改過的文件要提交&#xff0c;對比發現文件全部修改&#xff0c;但找不到不一樣的地方…

stringwriter_Java StringWriter getBuffer()方法與示例

stringwriterStringWriter類的getBuffer()方法 (StringWriter Class getBuffer() method) getBuffer() method is available in java.io package. getBuffer()方法在java.io包中可用。 getBuffer() method is used to get the StringBuffer that holds the present buffer valu…

linux 下郵件服務器,Linux 下搭建Postfix郵件服務器

Linux 下搭建Postfix郵件服務器詳解&#xff1a;1、首先關閉sendmail服務service sendmail stop2、chkconfig sendmail off(關閉開機自啟動)3、修改DNS正解文件&#xff0c;使DNS能夠解析郵箱服務添加下面兩行mail.zhubf.com. IN A 172.17.17.2zhubf.com. IN M…

Java PipedInputStream close()方法與示例

PipedInputStream類close()方法 (PipedInputStream Class close() method) close() method is available in java.io package. close()方法在java.io包中可用。 close() method is used to close this PipedInputStream and free all system resources linked with this stream…

Coreseek Windows下安裝調試

由于項目需要全文檢索&#xff0c;后面就去網上查了下資料&#xff0c;找到了Sphinx【中文是獅身人面像】這個全文檢索引擎&#xff0c;聽說挺好用的&#xff0c;不過沒有中文分詞。后面又去找了一下&#xff0c;找到了Coreseek&#xff0c;一款中文全文檢索/搜索軟件。 一、Sp…

linux sudo命令全稱,linux sudo命令的概念與使用

1.sudo介紹本文引用地址&#xff1a;http://www.eepw.com.cn/article/201610/305498.htmsudo是linux下常用的允許普通用戶使用超級用戶權限的工具&#xff0c;允許系統管理員讓普通用戶執行一些或者全部的root命令&#xff0c;如halt&#xff0c;reboot&#xff0c;su等等。這樣…

java 方法 示例_Java語言環境getISOCountries()方法與示例

java 方法 示例區域設置類getISOCountries()方法 (Locale Class getISOCountries() method) getISOCountries() method is available in java.util package. getISOCountries()方法在java.util包中可用。 getISOCountries() method is used to return an array of string that …

android shape.xml 屬性詳解

轉載源:http://blog.csdn.net/harvic880925/article/details/41850723 一、簡單使用 剛開始&#xff0c;就先不講一堆標簽的意義及用法&#xff0c;先簡單看看shape標簽怎么用。 1、新建shape文件 首先在res/drawable文件夾下&#xff0c;新建一個文件&#xff0c;命名為&#…