Singleton 同一個程式同時只能啟動一個執行個體

來源:互聯網
上載者:User

Java:同一個程式同時只能啟動一個執行個體 

import java.io.File;

import java.io.RandomAccessFile;

import java.nio.channels.FileChannel;

import java.nio.channels.FileLock;

public class SingleApplication {

    // 在應用程式的main方法裡調用此函數保證程式只有一個執行個體在運行.

    public static void makeSingle(String singleId) {

        RandomAccessFile raf = null;

        FileChannel channel = null;

        FileLock lock = null;

        try {

            // 在臨時檔案夾建立一個臨時檔案,鎖住這個檔案用來保證應用程式只有一個執行個體被建立.

            File sf = new File(System.getProperty("java.io.tmpdir") + singleId + ".single");

            sf.deleteOnExit();

            sf.createNewFile();

            raf = new RandomAccessFile(sf, "rw");

            channel = raf.getChannel();

            lock = channel.tryLock();

            if (lock == null) {

                // 如果沒有得到鎖,則程式退出.

                // 沒有必要手動釋放鎖和關閉流,當程式退出時,他們會被關閉的.

                throw new Error("An instance of the application is running.");

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public static void main(String[] args) throws Exception {

        SingleApplication.makeSingle("single.test"); // 保證程式只有一個執行個體在運行.

        // 測試: 類比一個程式正在運行5秒

        System.out.println("Start");

        System.out.println("Waiting 5 seconds.");

        for (int i = 0; i < 5; ++i) {

            Thread.sleep(1000);

            System.out.println((i + 1) + "......");

        }

        System.out.println("End");

    }

}

下面找了找管理Singleton方面的知識,有Java的,有C++的,先寫在這裡以後在慢慢補充吧。

單態定義:
Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個執行個體存在。在很多操作中,比如建立目錄 資料庫連接都需要這樣的單線程操作。

還有, singleton能夠被狀態化; 這樣,多個單態類在一起就可以作為一個狀態倉庫一樣向外提供服務,比如,你要論壇中的文章計數器,每次瀏覽一次需要計數,單態類能否保持住這個計數,並且 能synchronize(同步)的安全自動加1,如果你要把這個數字永久儲存到資料庫,你可以在不修改單態介面的情況下方便的做到。

另外方面,Singleton也能夠被無狀態化。提供工具性質的功能,

Singleton模式就為我們提供了這樣實現的可能。使用Singleton的好處還在於可以節省記憶體,因為它限制了執行個體的個數,有利於Java記憶體回收(garbage collection)。

我們常常看到原廠模式中類裝入器(class loader)中也用Singleton模式實現的,因為被裝入的類實際也屬於資源。
如何使用?
一般Singleton模式通常有幾種形式:

[java] view plaincopy

public class Singleton {  

  

  private Singleton(){}  

  

  //在自己內部定義自己一個執行個體,是不是很奇怪?  

  //注意這是private 只供內部調用  

  

  private static Singleton instance = new Singleton();  

  

  //這裡提供了一個供外部存取本class的靜態方法,可以直接存取    

  public static Singleton getInstance() {  

    return instance;   

   }   

}  

第二種形式: 

[java] view plaincopy

public class Singleton {  

  private static Singleton instance = null;  

  

  public static synchronized Singleton getInstance() {  

  

  if (instance==null)  

    instance=new Singleton();  

  return instance; }  

  

}  

使用Singleton.getInstance()可以訪問單態類。

上面第二中形式是lazy initialization,也就是說第一次調用時初始Singleton,以後就不用再產生了。

注意到lazy initialization形式中的synchronized,這個synchronized很重要,如果沒有synchronized,那麼使用 getInstance()是有可能得到多個Singleton執行個體。關於lazy initialization的Singleton有很多涉及double-checked locking (DCL)的討論,有興趣者進一步研究。一般認為第一種形式要更加安全些。 
使用Singleton注意事項:
有時在某些情況下,使用Singleton並不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分布式系統中使用也要注意這種情況,因為EJB是跨伺服器,跨JVM的。

我們以SUN公司的寵物店源碼(Pet Store 1.3.1)的ServiceLocator為例稍微分析一下:

在Pet Store中ServiceLocator有兩種,一個是EJB目錄下;一個是WEB目錄下,我們檢查這兩個ServiceLocator會發現內容差不 多,都是提供EJB的查詢定位服務,可是為什麼要分開呢?仔細研究對這兩種ServiceLocator才發現區別:在WEB中的 ServiceLocator的採取Singleton模式,ServiceLocator屬於資源定位,理所當然應該使用Singleton模式。但是 在EJB中,Singleton模式已經失去作用,所以ServiceLocator才分成兩種,一種面向WEB服務的,一種是面向EJB服務的。

Singleton模式看起來簡單,使用方法也很方便,但是真正用好,是非常不容易,需要對Java的類 線程 記憶體等概念有相當的瞭解。
總之:如果你的應用基於容器,那麼Singleton模式少用或者不用,可以使用相關替代技術。

Eclipse中GEF和EMF外掛程式設計模式總結

GEF(Graphical Editor Framework)是一個圖形化編輯架構,它允許開發人員以圖形化的方式展示和編輯模型,從而提升使用者體驗。使用GEF可以方便的實現XML編輯器、UML類圖編輯器等應用程式。

EMF(Eclipse Modelling Framework)是Eclipse MDA(Model Driven Architecture)的重要組成部分,可以將模型轉換成高效的,正確的,易於定製的Java代碼。

基於GEF和EMF可以很方便地進行模型驅動開發(Model-Driven Development,MDD),本文在研究生畢業設計中,將GEF和EMF外掛程式結合起來,開發一個基於物件導向Petri網(一種Petri 網,Petri網是描述非同步、並發的電腦系統模型的一種數學表示)的圖形化編輯器外掛程式。期間,接觸到了這兩個外掛程式中使用到的一些設計模式,和大家分享 一下。

1. MVC

GEF使用MVC架構消除模型與視圖之間的耦合:
(1) Model: 可以用任何Java對象來表示,model必須擁有某種notification機制。
(2) View: Figure/TreeItems,在典型的GraphicalEditor中,Figure是用於在GraphicalViewer中顯示的 Draw2D Figure,而TreeItems用於在Outline中的TreeViewer中顯示資訊。
(3) Controller: 通常對於每個Figure對應一個EditPart,EditPart用於控制模型與視圖,很多修改任務都是通過EditPolicy來實現的。

2. Command

GEF中的Command封裝了對模型Model的修改,可以通過繼承GEF中的抽象類別Command,提供可Redo/Undo功能,我們主要是在execute()/redo()/undo()中完成業務功能的實現。

3. Chain of Responsibility

Chain of Responsibility通過將Request傳遞給多個對象,並給這些對象機會處理請求,從而將請求的寄件者和接受者解除耦合。在GEF中,多個 EditPolicy可以收到請求,返回Commands,這些Commands以鏈的方式組織在一起。
另外,以及EMF中的訊息分發機制。

4. State

允許Graphical Editor在內部狀態發生改變的時候,修改編輯器的行為。對於GEF Editor,使用者切換工具可以改變編輯器的狀態。例如,對於滑鼠按下事件,編輯器在啟用選區工具和啟用建立工具下的行為是截然不同的。詳細請見 org.eclipse.gef.Tool介面,AbstractTool定義了幾個state,STATE_xxx.

5. Abstract Factory

GEF提供Interface建立一系列相關或相依賴的對象。這個模式在根據模型組件建立編輯組件時被使用。
GEF中根據EditPartFactory建立不同的EditPart,EMF中提供建立模型元素的工廠類ModelElementFactory。

6. Factory Method

定義了方法建立對象,但是允許子類決定執行個體化的類。這個模式沒有被單獨討論,但是它是建立編輯組件的另一種可選的方法。createChild方法允許你不使用工廠就建立子編輯組件。

7. Adapter

GEF的控制器EditPart中的getAdapter(Class key)方法。
EMF的Notifier-Adapter機制。

8. Singleton

Eclipse外掛程式工程的Single plugin instance類AbstractUIPlugin,保證外掛程式運行後只被執行個體化一次。

9. Composite

GEF中的各個顯示圖元composite之間以組合關係存在。
EMF中複合模型與子模型之間也以組合關係關在。

10. Observer

GEF中EditPart作為觀察者被註冊到EMF的模型對象中,監測模型的變化並通知視圖進行更新。

總結

通過大量使用設計模式,達到GEF和EMF外掛程式的靈活性和擴充性,便於開發。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.