### 延遲加載的單例多線程設計模式(懶漢式)??
單例模式
是讓調用者只產生一個唯一的對象。
分為餓漢式和懶漢式
**餓漢式:**
~~~
class EHan{
private static final EHan e = new EHan();
public eHan(){}
public static EHan getInstance(){
return e;
}
}
~~~
**懶漢式:**
~~~
class LanHan{
private static LanHan e = new LanHan();
public LanHan(){}
public static LanHan getInstance(){
if(e == null){
e = new LanHan();
return e;
}
return e;
}
}
~~~
這里懶漢式的寫法存在多線程的安全性問題,通過同步鎖來解決這個問題。
~~~
class LanHan{
private static LanHan e = new LanHan();
public LanHan(){}
public static LanHan getInstance(){
if(e == null){ //這種寫法,減少判斷同步鎖的次數,并同樣達到同步代碼的作用。
synchronized(LanHan.class){
if(e == null){
e = new LanHan();
return e;
}
}
}
return e;
}
}
~~~
### 死鎖的產生原因
1)產生原因:同步代碼中嵌套同步.
2)當flag為true時,同步代碼塊(定義為代碼塊1)拿到objA的鎖,執行代碼塊中的內容。接著要拿到objB的鎖,
此時flag為false,值行flag為false的代碼(定義為2),同步代碼塊拿到objB的鎖,需要拿到objA的鎖,還沒有執行完代碼塊中的代碼,并沒有釋放objB的鎖。
因此代碼塊1拿不到objB的鎖,代碼快沒有執行完,不釋放objA的鎖。
因此產生了死鎖。
~~~
class SyncRunnable implements Runnable{
public boolean flag = false;
public static Object objA = new Object();
public static Object objB = new Object();
public void run(){
if(flag){
while(true){ //定義為:代碼塊1
synchronized(objA){ //objA鎖
System.out.println("if objA----");
synchronized(objB){ //objB鎖
System.out.println("if objB----");
}
}
}
}else{
while(true){ // 定義為:代碼塊 2
synchronized(objB){ //objB鎖
System.out.println("else objB----");
synchronized(objA){ //objA鎖
System.out.println("else objA----");
}
}
}
}
}
}
public class SingleInstance{
public static void main(String args[]){
SyncRunnable sr1 = new SyncRunnable();
sr1.flag = true;
SyncRunnable sr2 = new SyncRunnable();
sr2.flag = false;
Thread t1 = new Thread(sr1);
Thread t2 = new Thread(sr2);
t1.start();
t2.start();
}
}
~~~