关于多线程:Java:从Runnable返回结果

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

我读了一篇关于回调的文章

可运行的返回值

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


使用ExecutorService方法,特别是返回Futuresubmit(Callable)方法,可以调用get()isDone()方法来检索结果:

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)

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


您可以尝试这样做:

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