Search code examples
javamultithreadingmultitaskingcallable

Callable in a separate thread vs. Runable and mulitasking


Sorry for my slightly "beginner" question related to the running of computations in a separate thread, but I am a C++ programmer.

There is a computationally expensive task processing large images. During the processing I would like to be able to work with my software (including zoom operations).

Based on your advice (the procedure returns data - a new image) the Callable interface has been used:

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

Initially, the executor service is created:

ExecutorService exe = Executors.newFixedThreadPool(2); 
B b = new B(true);

Subsequently, the future is returned:

Future<BufferedImage> res = exe.submit(b);

Finally, we are waiting for the data:

BufferedImage img = res.get(); 

Unfortunately, this implementation does not behave the way I expected. Although it works in a separate thread, the "response" is not returned to the main window and I am not able to work with the software properly during the computation.

Therefore, I tried to modify the get() method so that

try
{
    BufferedImage img_proj = results.get(5, TimeUnit.MILLISECONDS);
}

catch (Exception e)
{
     results.cancel(true);
     e.printStackTrace();
}

However, the TimeoutException appears. Rewriting the code back using the Runnable interface

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

together with

Thread t = new Thread(b);
t.start (); 

and the multitasking works as expected...

So my question is: Is it necessary to "tune" or tweak the Callable interface additionally and if so, how?


Solution

  • I would suggest using your executor service.

    exe.submit(()->{
        BufferedImage img = res.get();
        uiRelatedMethod(img);
    });
    

    That way your gui thread doesn't block, and it will get notified once the buffered image is available. Of course you'll have to use a try/catch block.