2012-02-03 62 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... 
}