2012-09-25 88 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"); 
    } 
}