Java: return results from Runnable
假设下面的简化示例。让b表示处理某些光栅数据的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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表示将在其中运行过程的类。它还包含一些等待线程完成的后处理步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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中使用b"inside"run()方法的process()方法创建最终的光栅?
当输出图像与
1 | b.getImage(); |
我读了一篇关于回调的文章
可运行的返回值
但是如何在这里实现呢?谢谢你的帮助和一个简短的例子。
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class B implements Callable<BufferedImage> { 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, e.g. in your A.compute() method ExecutorService exe = Executors.newFixedThreadPool(2); // Two threads in parallel B b = new B(true); Future<BufferedImage> 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 (i.e. b.call() returns) |
您可以使用不同风格的
您可以尝试这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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(); } } |
1 2 3 4 5 6 7 8 9 10 |