導航:首頁 > 編程語言 > java單例synchronized

java單例synchronized

發布時間:2022-09-05 07:10:10

❶ 什麼是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,以後就不用再生成了。

❷ 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,以後就不用再生成了。
注重到lazy
initialization形式中的synchronized,這個synchronized很重要,假如沒有synchronized,那麼使用getInstance()是有可能得到多個Singleton實例。
一般來說第一種比較安全。進入討論組討論。

❸ java與模式,懶漢式單例類的synchronized作用

如果多個線程在同一時刻訪問時就會出現意外。

❹ java 單例模式這個要怎麼理解

單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。
這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。
注意:
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
介紹

意圖:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
主要解決:一個全局使用的類頻繁地創建與銷毀。
何時使用:當您想控制實例數目,節省系統資源的時候。
如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則創建。
關鍵代碼:構造函數是私有的。
應用實例:
1、一個班級只有一個班主任。
2、Windows 是多進程多線程的,在操作一個文件的時候,就不可避免地出現多個進程或線程同時操作一個文件的現象,所以所有文件的處理必須通過唯一的實例來進行。
3、一些設備管理器常常設計為單例模式,比如一個電腦有兩台列印機,在輸出的時候就要處理不能兩台列印機列印同一個文件。
優點:
1、在內存里只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例(比如管理學院首頁頁面緩存)。
2、避免對資源的多重佔用(比如寫文件操作)。
缺點:沒有介面,不能繼承,與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來實例化。
使用場景:
1、要求生產唯一序列號。
2、WEB 中的計數器,不用每次刷新都在資料庫里加一次,用單例先緩存起來。
3、創建的一個對象需要消耗的資源過多,比如 I/O 與資料庫的連接等。
注意事項:getInstance() 方法中需要使用同步鎖 synchronized (Singleton.class) 防止多線程同時進入造成 instance 被多次實例化。

❺ 如何在Java中實現單例模式

單例模式大致有五種寫法,分別為懶漢,惡漢,靜態內部類,枚舉和雙重校驗鎖。

1、懶漢寫法,常用寫法

classLazySingleton{
;
privateLazySingleton(){
}
(){
if(singleton==null){
singleton=newLazySingleton();
}
returnsingleton;
}
}

2、惡漢寫法,缺點是沒有達到lazy loading的效果

classHungrySingleton{
=newHungrySingleton();
privateHungrySingleton(){}
(){
returnsingleton;
}
}

3、靜態內部類,優點:載入時不會初始化靜態變數INSTANCE,因為沒有主動使用,達到Lazy loading

classInternalSingleton{
{
=newInternalSingleton();
}
privateInternalSingleton(){}
(){
returnSingletonHolder.INSTANCE;
}
}

4、枚舉,優點:不僅能避免多線程同步問題,而且還能防止反序列化重新創建新的對象

enumEnumSingleton{
INSTANCE;
publicvoiddoSomeThing(){
}
}

5、雙重校驗鎖,在當前的內存模型中無效

classLockSingleton{
;
privateLockSingleton(){}

//詳見:http://www.ibm.com/developerworks/cn/java/j-dcl.html
(){
if(singleton==null){
synchronized(LockSingleton.class){
if(singleton==null){
singleton=newLockSingleton();
}
}
}
returnsingleton;
}
}

參考自:http://www.oschina.net/code/snippet_107039_6062

❻ 請教關於JAVA 單例中的Synchronized

當兩個並發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。
如果沒有synchronized,當兩個線程同時訪問單例方法,就有兩個單例同時被創建,違背了單例的原則。有了synchronized,當一個線程來訪問時另一個被拒絕在外面,當一個創建好了之後另一個再進來會有intance==null判斷,不能被創建,所以單例模式就保證了只會有一個實例被創建。

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

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

❽ 單例模式 java 雙重鎖用synchronized修飾之後還用volatile嗎

沒有volatile修飾的uniqueInstance

[java] view plain
public class Singleton {
private static Singleton uniqueInstance;

private Singleton(){
}

public static Singleton getInstance(){
if(uniqueInstance == null){ //#1
synchronized(Singleton.class){ //#2
if(uniqueInstance == null){ //#3
uniqueInstance = new Singleton(); //#4
System.out.println(Thread.currentThread().getName() + ": uniqueInstance is initalized..."); //#5.1
} else {
System.out.println(Thread.currentThread().getName() + ": uniqueInstance is not null now..."); //#5.2
}
}
}
return uniqueInstance;
}
}

這樣可能會導致結果 Singleton被實例化兩次 ,這樣就不符合單例的特點

原因分析:
1. thread2進入#1, 這時子線程的uniqueInstance都是為空的,thread2讓出CPU資源給thread3
2. thread3進入#1, 這時子線程的uniqueInstance都是為空的, thread3讓出CPO資源給thread2
3. thread2會依次執行#2,#3,#4, #5.1,最終在thread2裡面實例化了uniqueInstance。thread2執行完畢讓出CPO資源給thread3
4. thread3接著#1跑下去,跑到#3的時候,由於#1裡面拿到的uniqueInstance還是空(並沒有及時從thread2裡面拿到最新的),所以thread3仍然會執行#4,#5.1
5. 最後在thread2和thread3都實例化了uniqueInstance

例子2:用volatile修飾的uniqueInstance
這里就不貼重復的代碼了,因為只是加多一個volatile來修飾成員變數:uniqueInstance,
這樣可以創建出一個單例實例。

原因分析:
volatile(java5):可以保證多線程下的可見性;
讀volatile:每當子線程某一語句要用到volatile變數時,都會從主線程重新拷貝一份,這樣就保證子線程的會跟主線程的一致。
寫volatile: 每當子線程某一語句要寫volatile變數時,都會在讀完後同步到主線程去,這樣就保證主線程的變數及時更新。
1. thread2進入#1, 這時子線程的uniqueInstance都是為空的(java內存模型會從主線程拷貝一份uniqueInstance=null到子線程thread2),thread2讓出CPU資源給thread3
2. thread3進入#1, 這時子線程的uniqueInstance都是為空的(java內存模型會從主線程拷貝一份uniqueInstance=null到子線程thread2), thread3讓出CPO資源給thread2
3. thread2會依次執行#2,#3,#4, #5.1,最終在thread2裡面實例化了uniqueInstance(由於是volatile修飾的變數,會馬上同步到主線程的變數去)。thread2執行完畢讓出CPO資源給thread3
4. thread3接著#1跑下去,跑到#3的時候,會又一次從主線程拷貝一份uniqueInstance!=null回來,所以thread3就直接跑到了#5.2
5. 最後在thread3不再會重復實例化uniqueInstance了

閱讀全文

與java單例synchronized相關的資料

熱點內容
怎樣製作文件夾和圖片 瀏覽:58
調研編譯寫信息 瀏覽:859
python馮諾依曼 瀏覽:417
同時安裝多個app有什麼影響 瀏覽:252
奧術殺戮命令宏 瀏覽:182
用sdes加密明文字母e 瀏覽:359
單片機原理及應用試題 瀏覽:423
易語言開啟指定文件夾 瀏覽:40
馬思純參加密室大逃脫 瀏覽:322
文件夾冬季澆築溫度 瀏覽:712
京東有返點的aPp叫什麼 瀏覽:603
如何查看u點家庭伺服器是幾兆 瀏覽:262
python應用介面怎麼接 瀏覽:67
腐蝕怎麼進不去伺服器啊 瀏覽:359
linuxcpiogz 瀏覽:630
安卓中的布局是什麼文件 瀏覽:397
dex反編譯部分代碼無法查看 瀏覽:464
linuxandroid編譯 瀏覽:603
程序員電視劇20集 瀏覽:910
怎麼擴建文件夾 瀏覽:160