關於Java單例對象同步問題

來源:互聯網
上載者:User

單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個執行個體存在。正是由於這個特點,單例對象通常作為程式中的存放配置資訊的載體,因為它能保證其他對象讀到一致的資訊。例如在某個伺服器程式中,該伺服器的配置資訊可能存放在資料庫或檔案中,這些配置資料由某個單例對象統一讀取,服務進程中的其他對象如果要擷取這些配置資訊,只需訪問該單例對象即可。這種方式極大地簡化了在複雜環境下,尤其是多線程環境下的組態管理,但是隨著應用情境的不同,也可能帶來一些同步問題。

本文將探討一下在多線程環境下,使用單例對象作配置資訊管理時可能會帶來的幾個同步問題,並針對每個問題給出可選的解決辦法。

問題描述

在多線程環境下,單例對象的同步問題主要體現在兩個方面,單例對象的初始化和單例對象的屬性更新。

本文描述的方法有如下假設:

1. 單例對象的屬性(或成員變數)的擷取,是通過單例對象的初始化實現的。也就是說,在單例對象初始化時,會從檔案或資料庫中讀取最新的配置資訊。

2. 其他對象不能直接改變單例對象的屬性,單例對象屬性的變化來源於設定檔或設定資料庫資料的變化。

1.1 單例對象的初始化

首先,討論一下單例對象的初始化同步。單例模式的通常處理方式是,在對象中有一個靜態成員變數,其類型就是單例類型本身;如果該變數為null,則建立該單例類型的對象,並將該變數指向這個對象;如果該變數不為null,則直接使用該變數。

其過程如下面代碼所示:

public class GlobalConfig {
   private static GlobalConfig instance = null;
   private Vector properties = null;
   private GlobalConfig() {
    //Load configuration information from DB or file
    //Set values for properties
   }
   public static GlobalConfig getInstance() {
    if (instance == null) {
     instance = new GlobalConfig();
    }
    return instance;
   }
   public Vector getProperties() {
    return properties;
   }
  }

這種處理方式在單線程的模式下可以很好的運行;但是在多線程模式下,可能產生問題。如果第一個線程發現成員變數為null,準備建立對象;這是第二個線程同時也發現成員變數為null,也會建立新對象。這就會造成在一個JVM中有多個單例類型的執行個體。如果這個單例類型的成員變數在運行過程中變化,會造成多個單例類型執行個體的不一致,產生一些很奇怪的現象。例如,某服務進程通過檢查單例對象的某個屬性來停止多個線程服務,如果存在多個單例對象的執行個體,就會造成部分線程服務停止,部分線程服務不能停止的情況。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.