Java:从Runnable返回结果

假设以下简化示例。 设B表示处理某些栅格数据的类:

import java.awt.image.BufferedImage; public class B implements Runnable{ private boolean c; private Runnable f; public B (boolean c_, Runnable f_) { c = c_; f = f_;} public BufferedImage process() { //Some operations BufferedImage output = null; if (c) output = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); return output; } public void run() { process();} } 

process()方法可能但不能创建输出评估者。 由于计算成本,该过程在单独的线程中运行。

设A表示将在其中运行过程的类。 它还包含一些后续处理步骤,等待线程完成:

 import java.awt.image.BufferedImage; public class A { public A(){} public void compute() { boolean c = true; B b = new B( c, new Runnable() { public void run() { //Post process, after the thread has been finished BufferedImage img = ??? //Get resulting raster, how? if (img != null) { //Perform some steps } } }); Thread t = new Thread(b); t.start (); //Run procedure } } 

但是,如何使用A的process ()方法在A中的run()方法中创建生成的栅格?

当输出图像表示B的数据成员时,避免使用模型

 b.getImage(); 

我读了一篇关于回调的post

从Runnable返回值

但是如何在这里实现呢? 感谢您的帮助和一个简短的例子。

使用ExecutorService ,特别是它submit(Callable)方法,该方法返回一个Futureget() submit(Callable) get()isDone()方法来检索结果:

 public class B implements Callable { private boolean c; public B (boolean c) { this.c = c; } public BufferedImage call() { //Some operations if (!c) return null; return new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); } } // Somewhere, eg in your A.compute() method ExecutorService exe = Executors.newFixedThreadPool(2); // Two threads in parallel B b = new B(true); Future res = exe.submit(b); // Will return immediately. Processing will run in a thread of 'exe' executor // ... do things System.out.println("Finished: "+res.isDone()); BufferedImage img = res.get(); // Will block until image is available (iebcall() returns) 

您可以使用不同风格的ExecutorService ,您可以在其中对可能( submit(Callable) )或不execute(Runnable) )的处理进行排队,从而返回结果。 您要使用的执行程序类型取决于您需要的处理类型和顺序。

你可以尝试做这样的事情:

 public class B{ private boolean c; volatile boolean finished = false; // it can be shared among threads BufferedImage output; public B (boolean c_) { c = c_;} public void process() { Thread t = new Thread(new Runnable(){ @Override public void run() { if (c) output = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); finished = true; } }); t.start(); } } 

 public class A { public void compute() { B b = new B(true); b.process(); while(!b.finished){System.out.println("Processing");} // when finished check if output is not null // and then do some stuff if(b.output!=null){System.out.println(b.output);} } }