當前位置:首頁 » 編程語言 » java單例線程

java單例線程

發布時間: 2023-05-25 11:44:39

java線程安全的單例模式的幾種實現

四種線程安全的單例模式實現方式,其實並不局限於這四種,本文只是起一個拋磚引玉的作用。

㈡ java,單例對象的方法可以被多個線程同時調用嗎

同時是不可能的芹蔽旦,[單例]這個詞已經限定了,同一時刻只能有一個線程在訪問!其他一定在等待前者訪問結束!
很簡單,假如你說的成立,如果A正在修改,B正在訪問,數據一定錯誤!
單列是一種
設計嫌擾模式
,在你生成這個對象時候就已經限定了,同一時刻,只允許一條線程訪問並念!
如果你沒達到這個限定,那就不叫單列;
也就是說在你寫單列的時候,就已經考慮到
線程安全
問題!

㈢ 在java開發中,為什麼要使用單例模式

java單例模式確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例。

特點:

  1. 一個類只能有一個實例;

  2. 自己創建這個實例;

  3. 整個系統都要使用這個實例。

Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄 資料庫連接都需要這樣的單線程操作。一些資源管理器常常設計成單例模式。

外部資源:譬如每台計算機可以有若干個列印機,但只能有一個Printer Spooler,以避免兩個列印作業同時輸出到列印機中。每台計算機可以有若干個通信埠,系統應當集中管理這些通信埠,以避免一個通信埠被兩個請求同時調用。

內部資源,譬如,大多數的軟體都有一個(甚至多個)屬性文件存放系統配置。這樣的系統應當由一個對象來管理這些屬性文件。

單例模式,能避免實例重復創建;

單例模式,應用於避免存在多個實例引起程序邏輯錯誤的場合;

單例模式,較節約內存。

㈣ Java的單例模式是不是線程安全的

單例也不能保證100%線程安全的。解決方法就是創建實例方法中加入Java關鍵字synchronized。
Java語言的關鍵字synchronized,可叢轎用來給對象和方法或者代碼塊加鎖,當它鎖定一個方法或者一個代碼塊的滲薯肆時手頃候,同一時刻最多隻有一個線程執行這段代碼。當兩個並發線程訪問同一個對象object中的這個加鎖同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。然而,當一個線程訪問object的一個加鎖代碼塊時,另一個線程仍然可以訪問該object中的非加鎖代碼塊。

㈤ Java如何為每個線程提供一個單例

JAVA的單例模式只不過是讓這個類只能夠實例化一個對象就可以了,只要滿足這個要求就是單例模式,如脊頃果你寫的嚴謹點就是線程安全的,不嚴謹察褲就是線程不安全的。而且單例敗野簡模式還分為懶漢式單例模式和餓漢式單例模式

㈥ Java 中幾種常用的線程池

一:newCachedThreadPool
(1)緩存型池子,先查看池中有沒有以前建立的線程,如果有,就reuse,如果沒有,就建立一個新的線程加入池中;
(2)緩存型池子,通常用於執行一些生存周期很短的非同步型任務;因此一些面向連接的daemon型server中用得不多;
(3)能reuse的線程,必須是timeout IDLE內的池中線程,預設timeout是60s,超過這個IDLE時長,線程實例將被終止及移出池。
(4)注意,放入CachedThreadPool的線程不必擔心其結束,超過TIMEOUT不活動,其會自動被終止

二:newFixedThreadPool
(1)newFixedThreadPool與cacheThreadPool差不多,也是能reuse就用,但不能隨時建新的線程
(2)其獨特之處胡清賀:任意時間點,最多隻能有固定數目的活動線程存在,此時如果有新的線程要建立,只能放在另外的隊列中等待,直到當前的線程中某個線程終止直接被移出池子
(3)和正殲cacheThreadPool不同,FixedThreadPool沒有IDLE機制(可能也有,但既然文檔沒提,肯定非常長,類似依賴上層的TCP或UDP IDLE機制之類的),所以FixedThreadPool多數針對一些很褲派穩定很固定的正規並發線程,多用於伺服器
(4)從方法的源代碼看,cache池和fixed 池調用的是同一個底層池,只不過參數不同:
fixed池線程數固定,並且是0秒IDLE(無IDLE)
cache池線程數支持0-Integer.MAX_VALUE(顯然完全沒考慮主機的資源承受能力),60秒IDLE

三:ScheledThreadPool
(1)調度型線程池
(2)這個池子里的線程可以按schele依次delay執行,或周期執行
四:SingleThreadExecutor
(1)單例線程,任意時間池中只能有一個線程
(2)用的是和cache池和fixed池相同的底層池,但線程數目是1-1,0秒IDLE(無IDLE)

㈦ 關於JAVA單例的問題

這個問題由最開始使用JACKSON JSON而衍生出來 因為官網上建議將ObjectMapper作為全局變數使用從而提高效率 所以 我們項目裡面使用了單例 在使用單例的時候 我們無可厚非的考慮了資源在使用時是否要保證互斥的情況

最開始的寫法

Java代碼

public final class JacksonJsonMapper {

static volatile ObjectMapper objectMapper = null;

private JacksonJsonMapper(){}

public static ObjectMapper getInstance(){

if (objectMapper==null){

objectMapper = new ObjectMapper();

}

return objectMapper;

}

}

在此期間 我考慮了兩個問題 並與團隊中的另外一個兄弟發生了激烈的討論

在使用getInstance()方法的時候 是否要使用synchronized關鍵字

在使用objectMapper writeValueAsString(object)時 因為此方法非靜態方法 在此方法內是否會使用到對象自有的屬性 而在並發的時候出現前者屬性被後者銀並搏覆蓋的問題

後再看了源碼後 排除了第鋒祥二個顧慮 ObjectMapper是與線程綁定的 所以是線程安全的 並且也在官網的線程安全介紹中得到了證實

Jackson follows thread safety rules typical for modern factory based Java data format handlers (similar to what say Stax or JAXP implementations do) For example:

Factories (ObjectMapper JsonFactory) are thread safe once configured: so ensure that all configuration is done from a single thread and before instantiating anything with factory

Reader/writer instances (like JsonParser and JsonParser) are not thread safe there is usually no need for them to be but if for some reason you need to access them from multiple threads external synchronization is needed

All transformer objects (custom serializers deserializers) are expected to be stateless and thereby thread safe state has to be stored somewhere outside instances (in ThreadLocal or context objects passed in like DeserializationContext)

第一個顧慮在看完下面這篇文章蔽漏後 得到了解決方法

l

Java代碼

public final class JacksonJsonMapper {

static volatile ObjectMapper objectMapper = null;

private JacksonJsonMapper(){}

public static ObjectMapper getInstance(){

if (objectMapper==null){

synchronized (ObjectMapper class) {

if (objectMapper==null){

objectMapper = new ObjectMapper();

}

}

}

return objectMapper;

}

}

lishixin/Article/program/Java/gj/201311/27515

㈧ Java模式設計之單例模式(一)

作為對象的創建模式[GOF ] 單例模式確保某一個類只有一個實例 而且自行實例化並向整個系統提供這個實例 這個類稱為單例類

單例模式的要點

單例單例

顯然單例模式的要點有三個 一是某各類只能有一個實例 二是它必須自行創建這個事例 三是它必須自行向整個系統提供這個實例 在下面的對象圖中 有一個 單例對象 而 客戶甲 客戶乙 和 客戶丙 是單例對象的三個客戶對象 可以看到 所有的客戶對象共享一個單例對象 而且從單例對象到自身的連接線可以看出 單例對象持有對自己的引用

資源管理

一些資源管理器常常設計成單例模式

在計算機系統中 需要管理的資源包括軟體外部資源 譬如每台計算機可以有若干個列印機 但只能有一個Printer Spooler 以避免兩個列印作業同時輸出到列印機中 每台計算機可以有若干傳真卡 但是只應該有一個軟體負責管理傳真卡 以避免出現兩份傳真作業同時傳到傳真卡中的情況 每台計算機可以有若干通信埠 系統應當集中管理這些通信埠 以避免一個通信埠同時被兩個請求同時調用

需要管理的資源包括軟體內部資源 譬如 大多數的軟體都有一個(甚至多個)屬性(properties)文件存放系統配置 這樣的系統應當由一個對象來管理一個屬性文件

需要管理的軟體內部資源也包括譬如負責記錄網站來訪人數的部件 記錄軟體系統內部事件 出錯信息的部件 或是對系統的表念螞現進行檢查的部件等 這些部件都必須集中管理 不可政出多頭

這些資源管理器構件必須只有一個實例 這是其一 它們必須自行初始化 這是其二 允許整個系統訪問自己這是其三 因此 它們都滿足單例模式的條件 是單例模式的應用

一個例子 Windows 回收站

Windows x 以後的視窗系統中都有一個回收站 下圖就顯示了Windows 的回收站

在整個視窗系塵高核統中 回收站只能有一個實例 整個系統都使用這個惟一的實例 而且回收站自行提供自己的實例 因此 回收站是單例模式的應用

雙重檢查成例

在本章最後的附錄里研究了雙重檢查成例 雙重檢查成例與單例模式並無直接的關系 但是由於很多C 語言設計師在單例模式裡面使用雙重檢查成例 所以這一做法也被很多Java 設計師所模仿 因此 本書在附錄里提醒讀者 雙重檢查成例在Java 語言里並不能成立 詳情請見本章的附錄

單例模式的結構

單例模式有以下的特點

…… 單例類只可有一個實例

…… 單例類必須自己創建自己這惟一的實例

…… 單例類必須給所有其他對象提供這一實例

雖然單例模式中的單例類被限定只能有一個實例 但是單例模式和單例類可以很容易被推廣到任意且有限多個實例的情況 這時候稱它為多例模式(Multiton Pattern) 和多例類(Multiton Class) 請見 專題 多例(Multiton )模式與多語言支持 一章 單例類的簡略類圖如下所示

由於Java 語言的特點 使得單例模式在Java 語言的實現上有自己的特點 這些特點主要表現在單例類如何將自己實例化上

餓漢式單例類餓漢式單例類是在Java 語言里實現得最為簡便的單例類 下面所示的類圖描述了一個餓漢式單例類的典型實現

從圖中可以看出 此類已經自已將自己實例化

代碼清單 餓漢式單例類

public class EagerSingleton { private static final EagerSingleton m_instance = new EagerSingleton() /** * 私有的默認構造子*/ private EagerSingleton() { } /** * 靜態工廠方法*/ public static EagerSingleton getInstance()

{

Java 與模式return m_instance }

讀者可以看出 在這個類被載入時 靜態變數m_instance 會被初始化 此時類的私有構造子會被調用 這時候 單例類的惟一實例就被創建出來了

Java 語言中單例類的一個最重要的特點是類派掘的構造子是私有的 從而避免外界利用構造子直接創建出任意多的實例 值得指出的是 由於構造子是私有的 因此 此類不能被繼承

懶漢式單例類

與餓漢式單例類相同之處是 類的構造子是私有的 與餓漢式單例類不同的是 懶漢式單例類在第一次被引用時將自己實例化 如果載入器是靜態的 那麼在懶漢式單例類被載入時不會將自己實例化 如下圖所示 類圖中給出了一個典型的餓漢式單例類實現

代碼清單 懶漢式單例類

package javapatterns singleton demos public class LazySingleton { private static LazySingleton m_instance = null /** * 私有的默認構造子 保證外界無法直接實例化*/ private LazySingleton() { } /** * 靜態工廠方法 返還此類的惟一實例*/ synchronized public static LazySingleton getInstance()

{ if (m_instance == null)

{ m_instance = new LazySingleton() } return m_instance }

讀者可能會注意到 在上面給出懶漢式單例類實現里對靜態工廠方法使用了同步化 以處理多線程環境 有些設計師在這里建議使用所謂的 雙重檢查成例 必須指出的是 雙重檢查成例 不可以在Java 語言中使用 不十分熟悉的讀者 可以看看後面給出的小節

同樣 由於構造子是私有的 因此 此類不能被繼承 餓漢式單例類在自己被載入時就將自己實例化 即便載入器是靜態的 在餓漢式單例類被載入時仍會將自己實例化 單從資源利用效率角度來講 這個比懶漢式單例類稍差些

從速度和反應時間角度來講 則比懶漢式單例類稍好些 然而 懶漢式單例類在實例化時 必須處理好在多個線程同時首次引用此類時的訪問限制問題 特別是當單例類作為資源控制器 在實例化時必然涉及資源初始化 而資源初始化很有可能耗費時間 這意味著出現多線程同時首次引用此類的機率變得較大

餓漢式單例類可以在Java 語言內實現 但不易在C++ 內實現 因為靜態初始化在C++ 里沒有固定的順序 因而靜態的m_instance 變數的初始化與類的載入順序沒有保證 可能會出問題 這就是為什麼GoF 在提出單例類的概念時 舉的例子是懶漢式的 他們的書影響之大 以致Java 語言中單例類的例子也大多是懶漢式的 實際上 本書認為餓漢式單例類更符合Java 語言本身的特點

登記式單例類

登記式單例類是GoF 為了克服餓漢式單例類及懶漢式單例類均不可繼承的缺點而設計的 本書把他們的例子翻譯為Java 語言 並將它自己實例化的方式從懶漢式改為餓漢式 只是它的子類實例化的方式只能是懶漢式的 這是無法改變的 如下圖所示是登記式單例類的一個例子 圖中的關系線表明 此類已將自己實例化

代碼清單 登記式單例類

import java util HashMap public class RegSingleton { static private HashMap m_registry = new HashMap() static { RegSingleton x = new RegSingleton() m_registry put( x getClass() getName() x) } /** * 保護的默認構造子*/ protected RegSingleton() {} /** * 靜態工廠方法 返還此類惟一的實例*/ static public RegSingleton getInstance(String name)

{ if (name == null)

{ name = javapatterns singleton demos RegSingleton } if (m_registry get(name) == null)

{ try { m_registry put( name Class forName(name) newInstance() ) } catch(Exception e)

{ System out println( Error happened ) } return (RegSingleton) (m_registry get(name) ) } /** * 一個示意性的商業方法*/ public String about()

{ return Hello I am RegSingleton }它的子類RegSingletonChild 需要父類的幫助才能實例化 下圖所示是登記式單例類子類的一個例子 圖中的關系表明 此類是由父類將子類實例化的

下面是子類的源代碼

代碼清單 登記式單例類的子類

import java util HashMap public class RegSingletonChild extends RegSingleton { public RegSingletonChild() {} /** * 靜態工廠方法*/ static public RegSingletonChild getInstance()

{ return (RegSingletonChild)

RegSingleton getInstance( javapatterns singleton demos RegSingletonChild ) } /** * 一個示意性的商業方法*/ public String about()

{ return Hello I am RegSingletonChild }

在GoF 原始的例子中 並沒有getInstance() 方法 這樣得到子類必須調用的getInstance(String name)方法並傳入子類的名字 因此很不方便 本章在登記式單例類子類的例子里 加入了getInstance() 方法 這樣做的好處是RegSingletonChild 可以通過這個方法 返還自已的實例 而這樣做的缺點是 由於數據類型不同 無法在RegSingleton 提供這樣一個方法 由於子類必須允許父類以構造子調用產生實例 因此 它的構造子必須是公開的 這樣一來 就等於允許了以這樣方式產生實例而不在父類的登記中 這是登記式單例類的一個缺點

lishixin/Article/program/Java/gj/201311/27416

㈨ 什麼是Java單例模式啊

樓主您好
java模式之單例模式:
單例模式確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例。
特點:
1,一個類只能有一個實例
2,自己創建這個實例
3,整個系統都要使用這個實例
例: 在下面的對象圖中,有一個"單例對象",而"客戶甲"、"客戶乙" 和"客戶丙"是單例對象的三個客戶對象。可以看到,所有的客戶對象共享一個單例對象。而且從單例對象到自身的連接線可以看出,單例對象持有對自己的引用。

Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄 資料庫連接都需要這樣的單線程操作。一些資源管理器常常設計成單例模式。
外部資源:譬如每台計算機可以有若干個列印機,但只能有一個Printer Spooler,以避免兩個列印作業同時輸出到列印機中。每台計算機可以有若干個通信埠,系統應當集中管理這些通信埠,以避免一個通信埠被兩個請求同時調用。內部資源,譬如,大多數的軟體都有一個(甚至多個)屬性文件存放系統配置。這樣的系統應當由一個對象來管理這些屬性文件。

一個例子:Windows 回收站。
在整個視窗系統中,回收站只能有一個實例,整個系統都使用這個惟一的實例,而且回收站自行提供自己的實例。因此,回收站是單例模式的應用。

兩種形式:
1,餓漢式單例類
public class Singleton {

private Singleton(){}

//在自己內部定義自己一個實例,是不是很奇怪?
//注意這是private 只供內部調用

private static Singleton instance = new Singleton();

//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問
public static Singleton getInstance() {
return instance;
}
}

2,懶漢式單例類

public class Singleton {

private static Singleton instance = null;

public static synchronized Singleton getInstance() {

//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次

//使用時生成實例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }

}

第二中形式是lazy initialization,也就是說第一次調用時初始Singleton,以後就不用再生成了。

熱點內容
內置存儲卡可以拆嗎 發布:2025-05-18 04:16:35 瀏覽:336
編譯原理課時設置 發布:2025-05-18 04:13:28 瀏覽:378
linux中進入ip地址伺服器 發布:2025-05-18 04:11:21 瀏覽:613
java用什麼軟體寫 發布:2025-05-18 03:56:19 瀏覽:32
linux配置vim編譯c 發布:2025-05-18 03:55:07 瀏覽:107
砸百鬼腳本 發布:2025-05-18 03:53:34 瀏覽:945
安卓手機如何拍視頻和蘋果一樣 發布:2025-05-18 03:40:47 瀏覽:742
為什麼安卓手機連不上蘋果7熱點 發布:2025-05-18 03:40:13 瀏覽:803
網卡訪問 發布:2025-05-18 03:35:04 瀏覽:511
接收和發送伺服器地址 發布:2025-05-18 03:33:48 瀏覽:372