一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java 設計模式之單例模式

java 設計模式之單例模式

2020-08-14 15:47ionetwogo Java教程

這篇文章主要介紹了java 設計模式之單例模式的相關資料,需要的朋友可以參考下

java  設計模式單例模式

前言:

在軟件開發過程中常會有一些對象我們只需要一個,如:線程池(threadpool)、緩存(cache)、對話框、偏好設置等。這些對象如果制造出多個實例的話可能會導致一些不必要的麻煩,如:程序行為異常、資源使用過量等。這時單例模式就可以確保一個類只有一個實例,并提供全局訪問點。下面是從簡單的單例類來探討該用何種方法實現單例模式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 最經典的單例類
 */
public class Singleton {
  // 設置成靜態變量來記錄Singleton的唯一實例
  private static Singleton singleInstance;
  private Singleton(){
    // 構造方法聲明為私有的,這樣只能在Singleton類中才能調用此構造方法
  }
  /*
   * 獲取Singleton對象,如果還未實例化則實例化一個對象并返回這個實例
   */
  public static Singleton getInstance(){
    if (singleInstance == null) {
      singleInstance = new Singleton();
    }
    return singleInstance;
  }
  // 其他方法
}

從上面的例子可以看出Singleton類自己管理這個類的實例化過程,而且提供了全局訪問點,就是設置成靜態的getInstance()方法,在其他類要使用Singleton時它會返回一個實例。這中單例模式有個優點就是延遲實例化,簡單地說延遲實例化就是延遲初始化,在類需要時才創建其實例,而不是在開始加載這個類時就創建出一個實例,這樣的好處是可以避免性能的浪費。例如有些對象無需程序一開始就使用,或者其在程序執行的過程中就沒有使用過。但是此例子卻又一個缺點,那就是線程不夠安全。因為如果有多個線程同時執行到getInstance()方法,而Singleton又還未new Singleton()一個實例,那么線程就會都認為singleInstance為null,就都會實例化Singleton,這時就會產生多個Singleton實例,明顯不符合單例模式的初衷。那么接下來可能要做的就是對其進行改進

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class SingletonA {
  private static SingletonA singletongA;
  private SingletonA(){
 
  }
  /*
   * 增加synchronized關鍵字把getSingletonA方法變為同步方法
   */
  public static synchronized SingletonA getInstanceA(){
    if (singletongA == null) {
      singletongA = new SingletonA();
    }
    return singletongA;
  }
  // 其他方法
}

從這個例子上看增加了synchronized可以使getInstanceA()變成一個同步的方法,這時線程在進入這個方法之前就需要等待其他線程離開這個方法才能進入,也就使得該方法只能同時存在一個線程在執行它。

可能差不多問題解決了,但是要知道同步方法是會影響程序執行效率的,在此例子中我們只是為了解決第一個例子中第一次執行getInstance()方法不會產生多個實例,而這個例子中卻會導致每次需要實例時都會調用getInstanceA()同步方法,而在已經有實例之后的調用synchronized就會是累贅,因為我們已經無需擔心這個單例類會再次被創建出新的實例。因此我們還需要做一下改進。

既然上面說到延遲實例化,那么如果是不用的話那就簡單多了。

?
1
2
3
4
5
6
7
8
9
10
11
public class SingletonB {
  // 在靜態初始化器(static initializen)中創建單例,保證線程安全
  private static SingletonB singletonB = new SingletonB();
  private SingletonB(){
    // 構造函數
  }
  public static SingletonB getInstaceB(){
    // 已經實例化了,直接使用它
    return singletonB;
  }
}

上面的這種做法是在JVM加載這個類時馬上創建一個實例,因為JVM會在線程訪問這個實例之前就創建出該實例,因此線程是安全的。但這相較于延遲實例化而言可能會出現資源的浪費。而且如果此類較大的情況下會時程序初始化時間加長。

那么是否可以在使用用延遲實例化的同時又不會造成線程不安全且增加訪問效率呢。接下來就用雙重檢查加鎖來改進一下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * 雙重鎖單例模式
 */
public class SingletonC {
  private volatile static SingletonC singletonC;
  private SingletonC(){
 
  }
  public static SingletonC getInstanceC(){
    if (singletonC == null) {
      synchronized (SingletonC.class) {
        if (singletonC == null) {
          singletonC = new SingletonC();
        }
      }
    }
    return singletonC;
  }
}

上面的例子是先檢查實例,如果不存在則進入同步區塊,進入同步區塊之后再次檢查,如果還是null才會創建實例,因而singletonC = new SingletonC()只會執行一次,而之后調用getInstanceC()時就因為有實例直接返回,所以除了第一次調用時會走同步,而之后便不會如第二個例子那樣每次都會走同步方法。這樣就可以使得執行getInstanceC()的時間減少。想必這里會發現有個volatile關鍵字,其作用是使得singletonC被初始化后對所有線程可見,多個線程可以正確地處理這個SingletonC變量。但要注意的:volatile關鍵字只能在Java 5及其之后使用,如果在此版本之前會導致這個雙重檢查失效。

在使用單例模式時,如果有多個類加載器(classloader)時需要自行指定類加載器,并指定用一個類加載器。因為每個類加載器都定義了一個命名空間,不同的類加載器可能會加載同一個類,從而導致單例類創建出多個實例。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

原文鏈接:http://blog.csdn.net/qq_15128547/article/details/53205727

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜在线观看免费观看 视频 | 午夜精品久久久内射近拍高清 | 国产一久久香蕉国产线看观看 | 99精品全国免费7观看视频 | 99久久99热久久精品免费看 | 国产亚洲自愉自愉 | www在线看| 久久电影精品久久99久久 | 日韩首页 | 日本伊人色综合网 | h版小说 | 猫咪免费人成网站在线观看入口 | 国产精品麻豆99久久 | 国产高清在线看 | 欧美一区二区福利视频 | 白丝捆绑vk | 国产日韩一区二区 | 欧美精品v欧洲高清 | 国产精品视频久 | 久久久影院亚洲精品 | 久久久久久久尹人综合网亚洲 | 日韩首页 | miaa076深田咏美在线 | 国产成人一区二区三区影院免费 | 日本在线观看www鲁啊鲁视频 | 国产91区 | 无套日出白浆在线播放 | caonila国产在线观看 | 色在线免费 | 擦逼视频 | 国产乱码一卡二卡3卡四卡 国产乱插 | 日本公与妇中文在线 | 亚洲黄色成人 | 91麻豆网址 | 欧美另类xxx精品人妖 | 人人爱天天做夜夜爽88 | 天天爱综合网 | 日本不卡不码高清免费观看 | 国语刺激对白勾搭视频在线观看 | 九九大香尹人视频免费 | 无码精品一区二区三区免费视频 |