2012-09-25 87 views
0

我在我的类中有一个内部类,在父类上进行一些异步处理和设置值。例如:简单多线程java

class Myclass{ 
    String test; 

    public getTestValueFromMyClass(){ 
     //this starts asynchronous processing on my inner class 
    } 

    //inner class 
    class InnerClass extends TimerTask{ 
     //doing something asynchronously, when this process is done 
     test = "somevalue"; 
    } 
} 

现在,这里是亚军类问题:

class Runner{ 
    public static void main(String[] args){ 
     Myclass instance = new Myclass(); 

     //This is always null because runner class doesn't wait for Inner class to 
     //complete asynchronous processing and to set test value 
     System.out.println(instance.getTestValueFromMyClass()); 
    } 
} 

如何解决此得到什么?

+3

由于您似乎没有同时做任何事情,我只会使用一个线程。如果你想等待异步任务,我建议你使用ExecutorService和Future.get()。 –

+0

我不认为它会编译。 –

+0

是的,我打算等待异步任务完成,然后打印出结果,但我不知道如何 –

回答

2

也有人建议类似的想法,但我会使用一个单独的线程池与Callable

正在进行异步处理的类应执行Callable,它将返回计算的值。在这个例子中,它返回一个String,但它也可以返回你自己的对象和更多的信息。然后

public class MyClass implements Callable<String> { 
    public String call() { 
     //doing something asynchronously, when this process is done 
     return "somevalue"; 
    } 
} 

Runner类将创建一个线程池,断火在后台异步任务,再后来等待它完成。当您向线程池提交Callable作业时,会得到一个Future类,它可用于等待异步作业完成并获取其返回值。

public class Runner{ 
    public static void main(String[] args) { 
     // you can use newFixedThreadPool(...) if you need to submit multiple 
     ExecutorService threadPool = Executors.newSingleThreadExecutor(); 
     // you could store this future in a collection if you have multiple 
     Future<String> future = threadPool.submit(new MyClass()); 
     // after submitting the final job, we _must_ shutdown the pool 
     threadPool.shutdown(); 

     // do other stuff in the "foreground" while MyClass runs in the background 

     // wait for the background task to complete and gets its return value 
     // this can throw an exception if the call() method threw 
     String value = future.get(); 
     System.out.println(value); 
    } 
} 
0

处理完成后,您可以使用处理程序并发布消息!

+0

感谢您的回复,你有没有example/link,类似的东西我真的不知道你在说什么 –

+0

对不起,我的建议是针对Android develop.You不需要一个线程。但是如果你坚持有一个单独的线程,那么只需在处理完成后调用一个方法即可! –

0
class Myclass{ 
    // pre initialize thread pool 
    private static ExecutorService executor = Executors.newFixedThreadPool(5); 

    private String test; 

    public String getTestValueFromMyClass() throws Exception { 
     // start asynchronous calculations 
     Future<String> resultHandler = 
      executor.submit(new Callable<String>() { 
        @Override 
        public String call() throws Exception { 
         return "Asynchronously calculated result"; 
        } 
       }); 
     // do something in current thread 
     // ... 
     // wait until asynchronous task ends, get result 
     // and assign it to instance variable 
     this.test = resultHandler.get(); 

     return test; // returns string "Asynchronously calculated result" 
    } 
} 
+0

这将返回字符串异步计算结果,但我的程序仍在运行,为什么它不结束? –

+0

因为resultHandler.get()会在必要时等待计算完成,然后检索结果(也有存在timeout的'get'版本):http://docs.oracle.com/javase/1.5.0 /docs/api/java/util/concurrent/Future.html#get%28%29 – stemm

2

显然,你必须做出getTestValueFromMyClass等待InnerClass执行。这可以通过一些同步功能(信号量,CountdownLatch,BlockingQueue ...)来完成。但最直接的是使用java.util.concurrent.ScheduledThreadPoolExecutor而不是java.util.Timer。其方法schedule(Callable<V> callable, long delay, TimeUnit unit)返回Future,并且Future.get()等待并返回计算值。

2

一个非常简单的机制是使用BlockingQueue在你的线程之间进行通信。我在这里创建线程类中的队列,但它可以很容易地在调用者中创建并传递给线程。

public class Runner { 
    static class MyClass implements Runnable { 
    // Thread will post to this queue when it completes. 
    BlockingQueue q = new ArrayBlockingQueue(1); 

    // Call to wait for the post. 
    public void waitForFinish() throws InterruptedException { 
     // Just take! This will wait until something gets posted. 
     q.take(); 
    } 

    @Override 
    public void run() { 
     try { 
     // Just wait ten seconds. 
     Thread.sleep(10000); 
     } catch (InterruptedException ex) { 
     // Just exit when interrupted. 
     } finally { 
     try { 
      // Signal finished. 
      q.put("Done"); 
     } catch (InterruptedException ex) { 
      // Just exit when interrupted. 
     } 
     } 
    } 
    } 

    public static void main(String[] args) throws InterruptedException { 
    // Make my instance. 
    MyClass instance = new MyClass(); 
    // Fire it off. 
    new Thread(instance).start(); 
    // Wait for it to finish. 
    instance.waitForFinish(); 
    // All done. 
    System.out.println("Finished"); 
    } 
}