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外掛程式的靈活性和擴充性,便於開發。