如何实现一个真正的异步Java线程

问题描述:

我有一个函数需要执行两个操作,一个快速完成,一个需要很长时间才能运行。我希望能够将长时间运行的操作委托给一个线程,并且我不在乎线程何时完成,但线程需要完成。我按照如下所示实现了这一点,但是,我的第二个操作从来没有完成,因为函数在start()调用之后退出。我如何确保函数返回,但第二个操作线程完成其执行,并且不依赖于父线程?如何实现一个真正的异步Java线程

public void someFunction(String data) 
{ 
    smallOperation() 
    SecondOperation a = new SecondOperation(); 
    Thread th = new Thread(a); 
    th.Start(); 
} 

class SecondOperation implements Runnable 
{ 
    public void run(){ 
    // doSomething long running 
} 
} 
+2

你永远不会在你的'someFunction()'使用'SecondOperation',你怎么能指望它来运行? – 2010-04-20 16:10:29

+0

你甚至错过了分号: -/ – fortran 2010-04-20 17:01:46

+0

对不起,修复了我的代码中的错误。 – 2010-04-21 04:52:53

public void someFunction(final String data) { 
    shortOperation(data); 
    new Thread(new Runnable() { 
     public void run(){ 
      longOperation(data); 
     } 
    }).start(); 
} 

如果someFunction被调用时,JVM将运行longOperation如果

  1. 线程运行时,不标示 作为守护(在上面的代码 不是)
  2. longOperation()不会抛出异常并且
  3. 没有对System.exit()的调用longOperation()

在线程终止之前,JVM不会退出。你发布的这个代码甚至没有编译;也许问题出在你的实际代码中。

+0

我只写了代码的逻辑部分。 – 2010-04-20 17:03:41

+0

我不知道“逻辑部分”是什么意思,但是您提供的代码不是导致线程终止的部分。 – danben 2010-04-20 17:07:50

如果你的第二个函数没有完成,它与你的函数返回没有任何关系。如果某事调用System.exit()或者如果你的函数抛出一个异常,那么线程将停止。否则,即使主线程停止,它也会运行直到完成。可以通过将新线程设置为守护进程来阻止这种情况,但是您并未这样做。

+0

如何将新线程设置为守护进程? – 2010-04-20 17:04:01

+0

要明确,将其设置为守护进程将导致JVM在完成之前退出,前提是没有其他非守护进程线程正在运行。所以这与你想要的相反。在调用start()之前,可以通过在Thread对象*上调用setDaemon(true)来设置它。 – Yishai 2010-04-20 17:45:59

通过在临时线程中创建第二个线程来创建真正的异步线程。

(new Thread(new Runnable() { public void run() { 
    (new Thread(new Runnable() { public void run() 
    { 
     /* async thread */ 
    }})).start(); 
}})).start();