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

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

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|

服務器之家 - 編程語言 - JAVA教程 - Java中單例模式詳解

Java中單例模式詳解

2020-07-02 11:51會飛的小祥 JAVA教程

這篇文章主要介紹了Java中單例模式詳解,單例模式包括了懶漢式單例、餓漢式單例、登記式單例三種,想要了解的朋友可以了解一下。

單例模式概念:

java中單例模式是一種常見的設計模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。

單例模式有一下特點:

1、單例類只能有一個實例。

2、單例類必須自己自己創建自己的唯一實例。

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

單例模式確保某個類只有一個實例,而且自行實例化并向整個系統提供這個實例。在計算機系統中,線程池、緩存、日志對象、對話框、打印機、顯卡的驅動程序對象常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中。每臺計算機可以有若干通信端口,系統應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。

首先看一個經典的單例實現。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Singleton {
  private static Singleton uniqueInstance = null;
 
  private Singleton() {
    // Exists only to defeat instantiation.
  }
 
  public static Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqueInstance;
  }
  // Other methods...
}

Singleton通過將構造方法限定為private避免了類在外部被實例化,在同一個虛擬機范圍內,Singleton的唯一實例只能通過getInstance()方法訪問。(事實上,通過Java反射機制是能夠實例化構造方法為private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認為反射機制不存在。)

但是以上實現沒有考慮線程安全問題。所謂線程安全是指:如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。或者說:一個類或者程序所提供的接口對于線程來說是原子操作或者多個線程之間的切換不會導致該接口的執行結果存在二義性,也就是說我們不用考慮同步的問題。顯然以上實現并不滿足線程安全的要求,在并發環境下很可能出現多個Singleton實例。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class TestStream {
   private String name;
   public String getName() {
     return name;
   }
   public void setName(String name) {
     this.name = name;
   }
   //該類只能有一個實例
   private TestStream(){}  //私有無參構造方法
   //該類必須自行創建
   //有2種方式
   /*private static final TestStream ts=new TestStream();*/
   private static TestStream ts1=null;
   //這個類必須自動向整個系統提供這個實例對象
   public static TestStream getTest(){
     if(ts1==null){
       ts1=new TestStream();
     }
    return ts1;
   }
   public void getInfo(){
     System.out.println("output message "+name);
   }
 }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TestMain {
  public static void main(String [] args){
    TestStream s=TestStream.getTest();
    s.setName("張孝祥");
   System.out.println(s.getName());
    TestStream s1=TestStream.getTest();
    s1.setName("張孝祥");
    System.out.println(s1.getName());
    s.getInfo();
    s1.getInfo();
    if(s==s1){
      System.out.println("創建的是同一個實例");
   }else if(s!=s1){
      System.out.println("創建的不是同一個實例");
    }else{
      System.out.println("application error");
    }
  }
}

運行結果:

張孝祥
張孝祥
output message 張孝祥
output message 張孝祥
創建的是同一個實例

結論:由結果可以得知單例模式為一個面向對象的應用程序提供了對象惟一的訪問點,不管它實現何種功能,整個應用程序都會同享一個實例對象。

1.餓漢式單例類

?
1
2
3
4
5
6
7
8
9
10
11
//餓漢式單例類.在類初始化時,已經自行實例化
 public class Singleton1 {
   //私有的默認構造子
   private Singleton1() {}
   //已經自行實例化
   private static final Singleton1 single = new Singleton1();
   //靜態工廠方法
   public static Singleton1 getInstance() {
     return single;
   }
 }

 2.懶漢式單例類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//懶漢式單例類.在第一次調用的時候實例化
public class Singleton2 {
  //私有的默認構造子
  private Singleton2() {}
  //注意,這里沒有final 
  private static Singleton2 single=null;
  //靜態工廠方法
  public synchronized static Singleton2 getInstance() {
    if (single == null) {
      single = new Singleton2();
    }
   return single;
  }
}

 3.登記式單例類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.HashMap;
import java.util.Map;
//登記式單例類.
//類似Spring里面的方法,將類名注冊,下次從里面直接獲取。
public class Singleton3 {
  private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
  static{
    Singleton3 single = new Singleton3();
    map.put(single.getClass().getName(), single);
  }
  //保護的默認構造子
  protected Singleton3(){}
  //靜態工廠方法,返還此類惟一的實例
  public static Singleton3 getInstance(String name) {
    if(name == null) {
      name = Singleton3.class.getName();
      System.out.println("name == null"+"--->name="+name);
    }
    if(map.get(name) == null) {
      try {
        map.put(name, (Singleton3) Class.forName(name).newInstance());
      } catch (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
    }
    return map.get(name);
  }
  //一個示意性的商業方法
  public String about() { 
    return "Hello, I am RegSingleton."
  
  public static void main(String[] args) {
    Singleton3 single3 = Singleton3.getInstance(null);
   System.out.println(single3.about());
  }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 草莓香蕉绿巨人丝瓜榴莲18 | 色久久一个亚洲综合网 | 日本人与黑人做爰视频网站 | 日本mature乱子视频 | 日韩资源在线 | 果冻传媒在线视频观看免费 | 美女脱了内裤打开腿让人羞羞软件 | 免费在线观看亚洲 | 黑人又大又硬又粗再深一点 | 国产老熟 | 欧美伊人久久久久久久久影院 | 国产精品一区二区不卡的视频 | 99九九国产精品免费视频 | 亚洲AV无码国产精品色午夜情 | 欧美草逼视频 | 日韩在线观看一区二区不卡视频 | 波多野结衣之双方调教在线观看 | 午夜久久影院 | 国产va免费精品高清在线 | 精品久久久久国产免费 | 欧美成人中文字幕 | 精品久久香蕉国产线看观看亚洲 | 国产伦久视频免费观看视频 | 午夜A级理论片左线播放 | www.久久av.com | 毛片的网站 | 消息称老熟妇乱视频一区二区 | 好 舒服 好 粗 好硬 好爽 | 国产精品片 | 欧美又硬又粗又长又大 | 无颜之月全集免费观看 | 四虎影院在线 | 国产成人免费在线视频 | 国产拍拍拍免费专区在线观看 | 四虎地址8848aa4hc44四虎 四虎成人永久地址 | 国产大片免费在线观看 | 国产伦码精品一区二区三区 | 风间由美m3u8在线 | 国产成人精品高清免费 | 波多野结衣被绝伦强在线观看 | 91成人啪国产啪永久地址 |