2012-02-03 61 views
1

我們正在開發一個項目來處理來自Java應用程序的虛擬機管理器。線程中的異常處理

目前,我們遇到了一些問題,其中一些指令必須被視爲一項任務,因爲它們需要更多時間。這些提取也可能以錯誤結束或成功,除非我們向VM管理程序請求任務的狀態,否則我們無法知道應用程序的結果。

爲了獲得順利的應用程序,我們希望有一個CommandManager來處理分離線程中對這些hypervisors的不同請求。問題是,這些命令可能會返回特定的錯誤,例如我們用來捕捉視圖以向用戶顯示相關信息,但是當我們在我們的Commands界面上實現Runnable時,我們不能將該線程外的任何異常返回給達到觀點。

我能做些什麼來不斷通知用戶發生的錯誤和它們的性質?

對不起,我的英語!

讓我們來看看下面的一個簡單的例子代碼:

首先命令

class ChangeMemorySize extends Command { 
    private String name; 
    private int memorySizeMb; 

    public ChangeMemorySize(Hypervisor hypervisor, String server, 
      String name, int memory) { 
     super(hypervisor, server); 
     this.name = name; 
     this.memorySizeMb = memory; 
    } 
    protected void execute() throws ConnectionException,OperationException{ 

    //Some code here 

    } 
    public void run() //CANT THROW ANYTHING HERE :throws VmConfigFault, 
     try{ 
      execute(); 
     }catch{Exception e){ 
      // I have to catch it all here! 
     } 

這不是真正的代碼,這只是一個例子。然後這個命令將被傳遞給一個經理,他將在另一個線程中運行它。但是我放棄了所有的具體例外,我用它來通知用戶那裏發生了什麼!

+1

您是否嘗試過在調用的方法?去閱讀這兩個javadocs;如果不清楚,我會發佈一個更全面的答案。 – 2012-02-03 19:36:29

+0

我在看它謝謝 – David 2012-02-06 15:13:13

+0

我應該使用'未來'類嗎? – David 2012-02-06 15:25:15

回答

2

使用ExecutorService並執行以下兩項操作之一。

第一個您可以將所有結果存儲在Future中,當您想知道是否發生異常時,只需調用Future.get()並處理任何異常。

您可以用的ThreadFactory創建的ExecutorService在其中設置它知道的UncaughtExceptionHandler像

 final UncaughtExceptionHandler handler = new UncaughtExceptionHandler() { 
      public void uncaughtException(Thread t, Throwable e) { 
       // notify error 
      } 
     }); 
     Executor executor = Executors.newFixedThreadPool(1, new ThreadFactory() { 
      public Thread newThread(Runnable r) { 
       Thread thread = new Thread(r); 
       thread.setUncaughtExceptionHandler(handler); 
       return thread; 
      } 
     }); 
+0

我會爲您的第二項技術提供一個鏡頭,並瞭解我該如何處理它! – David 2012-02-06 14:30:56

+0

我唯一知道的事情是我將如何跟蹤來自這些不同請求線程的結果。 – David 2012-02-06 14:31:53

+1

我已經使用了Future類,它工作得很好! – David 2012-02-06 20:29:28

1

雖然我與@約翰的Vint同意的ExecutorService與UncaughtExceptionHandler的是一個好方法,如果出於某種原因,你真的想堅持使用Runnables,我建議你的基類Command包含一些用於狀態和Exception的字段/獲取器。例如

Enum Status {FAILED, CANCELLED, SUCCESS}; 

// protected so subclasses can set them 
protected Status status; 
protected Exception exception; // null means none 

public Status getStatus(); 
public Exception getException(); 

你甚至可能想要添加一個結果字段來真正模仿Callable。

爲了簡單起見,然後添加子類可以使用`ExecutorCompletionService`和`Callable`類的catch子句

protected void s***Happenned(Exception e) { 
    this.exception = e; 
    status = FAILED; 
    // any standard cleanup can go here too... 
}