1. 程式人生 > >執行緒安全的登記式單例

執行緒安全的登記式單例

有的時候,我們不希望在一開始的時候就把一個類寫成單例模式,但是在運用的時候,我們卻可以像單例一樣使用他

最典型的例子就是spring,他的預設型別就是單例,spring是如何做到把不是單例的類變成單例呢?

這就用到了登記式單例

其實登記式單例並沒有去改變類,他所做的就是起到一個登記的作用,如果沒有登記,他就給你登記,並把生成的例項儲存起來,下次你要用的時候直接給你。

IOC容器就是做的這個事,你需要就找他去拿,他就可以很方便的實現Bean的管理。

OK,我們來看看登記式單例是如何做的。

public class RegistSingleton {
    //用ConcurrentHashMap來維護對映關係,這是執行緒安全的
public static final Map<String,Object> REGIST=new ConcurrentHashMap<String, Object>(); static { //把RegistSingleton自己也納入容器管理 RegistSingleton registSingleton=new RegistSingleton(); REGIST.put(registSingleton.getClass().getName(),registSingleton); } private
RegistSingleton(){} public static Object getInstance(String className){ //如果傳入的類名為空,就返回RegistSingleton例項 if(className==null) className=RegistSingleton.class.getName(); //如果沒有登記就用反射new一個 if (!REGIST.containsKey(className)){ //沒有登記就進入同步塊 synchronized (RegistSingleton.class){ //再次檢測是否登記
if (!REGIST.containsKey(className)){ try { //例項化物件 REGIST.put(className,Class.forName(className).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } //返回單例 return REGIST.get(className); } }

寫一個測試方法:

public class Main {
    static CyclicBarrier cyclicBarrier=new CyclicBarrier(1000);
    public static void main(String[] args) {
        for (int i = 0; i <1000 ; i++) {
            int n = i;
            new Thread(()->{
                System.out.println("執行緒"+ n +"準備就緒");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(RegistSingleton.getInstance("singletonpattern.regist.ClassA"));
            }).start();
        }
    }
}

結果是執行緒安全的(ClassA是一個空類,裡面什麼也沒有)

PS:原始碼地址

相關推薦

C++設計一個執行安全的懶漢模式

#incldue<iostream> #include<mutex> using namespace std; class CSingleton { public: static CSingleton* GetCSingleton() { if (_p ==

執行安全登記

有的時候,我們不希望在一開始的時候就把一個類寫成單例模式,但是在運用的時候,我們卻可以像單例一樣使用他 最典型的例子就是spring,他的預設型別就是單例,spring是如何做到把不是單例的類變成單例呢? 這就用到了登記式單例 其實登記式單例並沒有去改變類

執行併發問題以及設計模式與執行安全以及同步方法和同步程式碼塊

執行緒安全和非執行緒安全 在作業系統中,執行緒是不擁有資源的,程序擁有資源。執行緒是由程序建立的,一個程序可以建立多個執行緒,這些執行緒共享程序中的資源。當多個執行緒同時操作一個變數時,這個時候就可能會造成資料的不一致性,此時就是執行緒不安全。 JVM有主記

Java 多執行(四)—— 模式

這篇部落格介紹執行緒安全的應用——單例模式。 單例模式   單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個例項。即一個類只有一個物件例項。 例項: /** * @author

如何正確實現多執行環境中的模式

要實現單例模式,馬上可以想到的有三種方法: 餓漢式 懶漢式 有且只有一個例項的列舉 如何正確地在多執行緒環境下實現單例模式呢? 對於 餓漢式 和 單例項列舉 來說,它們都是利用jvm類載入機制來實現單例模式。使用這兩種方法,無論是否是在多執行緒環境中,都

java day25 多執行(下) 類(Runtime,Timer

25.01_多執行緒(單例設計模式)(掌握) 單例設計模式:保證類在記憶體中只有一個物件。 如何保證類在記憶體中只有一個物件呢? (1)控制類的建立,不讓其他類來建立本類的物件。private (2)在本類中定義一個本類的物件。Singl

Java多執行核心技術(五)模式與多執行

本文只需要考慮一件事:如何使單例模式遇到多執行緒是安全的、正確的 1.立即載入 / "餓漢模式" 什麼是立即載入?立即載入就是使用類的時候已經將物件建立完畢,常見的實現辦法就是直接 new 例項化。 public class MyObject { private static MyObject m

C# 多執行啟動和管理 模式

1.          List<Task> taskList = new List<Task>();             TaskFactory t

C# 基礎(十四)C#模式:首先介紹 執行、多執行、加鎖 模式。然後介紹模式的執行同步:多執行有序訪問共享記憶體。

一、簡介 本篇文章將介紹如何使用單例模式,也就是類的例項化,在整個專案的生命週期內,只例項化一次。在單例模式中,往往可以看到如SourceCode.cs:這樣的結構的。 SourceCode.cs: public class Singleton { private static

執行併發下的模式實現

1.1 天生執行緒安全的餓漢式單例 1.2 懶漢式單例 1.2.1 執行緒不安全的懶漢式單例 1.2.2 執行緒安全的懶漢式單例

執行下的懶漢式模式

       在多執行緒下實現懶漢式單例模式是不安全的,所謂的不安全,就是在同一時間段有兩個執行緒同時執行一段程式碼。解決方法包括將懶漢式改為餓漢式或者讓執行緒同步。下面程式碼實現執行緒的同步,保證多

淺談多執行中的懶漢式

1.場景:我們都知道在應用開發中有時會使用到單例設計模式,那麼今天我們就淺談一下單例中的一種-懶漢式。 顧名思義懶漢式其實是一個很有意思的名字,懶漢在我們開發中常說的用到了才去建立物件。此種生成方式遇到多執行緒又會擦出怎樣的火花呢? public class Singlet

Java設計模式之模式之登記

package 建立型_單例模式_登記式; import java.util.HashMap; import java.util.Map; /** * 登記式單例實際上維護的是一組單例類的例項,將這些例項儲存到一個Map(登記簿) * 中,對於已經登記過的單例,則從

執行模式中的

單例相關知識參考《》。單例模式,最常見的就是飢餓模式、懶漢模式,一個直接例項化物件,一個在呼叫方法時進行例項化物件。在多執行緒模式中,考慮到效能和執行緒安全問題,我們一般選擇下面兩種比較經典的單例模式,在效能提高的同時,又保證了執行緒安全。dubble check insta

【多執行核心技術】---模式與多執行

立即載入/“餓漢模式”    立即載入就是在使用類的時候已經將物件建立完畢,常見的實現辦法就是直接new例項化。立即載入/“餓漢模式”    延遲載入就是在呼叫get()方法時例項化才被建立,常見的實現方式就是在get()方法中進行new()例項化,    在多執行緒環境下會

執行情況下,模式的實現方式

方式1(推薦)package singleton; public class Singletion { private static class InnerSingletion { priv

設計模式 - 模式之多執行除錯與破壞

前言 在之前的 設計模式 - 單例模式(詳解)看看和你理解的是否一樣? 一文中,我們提到了通過Idea 開發工具進行多執行緒除錯、單例模式的暴力破壞的問題;由於篇幅原因,現在單獨開一篇文章進行演示:執行緒不安全的單例在多執行緒情況下為何被建立多個、如何破壞單例。 如果還不知道如何使用IDEA工具進行執行緒模

java設計模式(一)建立型模式之 模式(餓漢,懶漢式,執行安全,雙重檢查)

1.介紹     單例模式是一種常用的軟體設計模式,其定義是單例物件的類只能允許一個例項存在。  2.實現思路與步驟   1).將該類的構造方法定義為私有方法,這樣其他處的程式碼就無法通過呼叫該類的構造方法來例項化該類的物件,只有通過該類提供的靜態

模式(懶漢式和餓漢)及如何實現執行安全

單例模式有兩種:懶漢式和餓漢式。 1 #include <iostream> 2 3 using namespace std; 4 5 6 // 保證在整個程式執行期間,最多隻能有一個物件例項 7 8 9 // 懶漢式 10 // 1 、建構函式私有化 11

餓漢執行安全問題以及提高效率

首先寫個單例: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} p