0

我有一个内部类在我的类中进行一些异步处理并在父类上设置值。前任 :

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";
   }
}

现在这是 Runner 类的问题:

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());
    }
}

我该如何解决这个问题?

4

5 回答 5

2

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

于 2012-09-25T12:54:43.847 回答
2

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

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");
  }
}
于 2012-09-25T13:07:19.133 回答
2

其他人提出了类似的想法,但我会使用带有Callable.

您正在执行异步处理的类应该实现Callable将返回计算值。在此示例中,它返回 aString但它也可以返回您自己的包含更多信息的对象。

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);
    }
}
于 2012-09-25T19:44:56.930 回答
0

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

于 2012-09-25T12:44:05.107 回答
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"
   }
}
于 2012-09-25T12:54:35.000 回答