15

With reference to the java.util.concurrent package and the Future interface I notice (unless I am mistaken) that the ability to start a lengthy tasks and be able to query on the progress only comes with the SwingWorker implementing class.

This begs the following question:

Is there a way, in a non-GUI, non-Swing application (imaging a console application) to start a lengthy task in the background and allow the other threads to inspect the progress ? It seems to me that there is no reason why this capability should be limited to swing / GUI applications. Otherwise, the only available option, the way I see it, is to go through ExecutorService::submit which returns a Future object. However, the base Future interface does not allow monitoring the progress.

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • 2
    See http://stackoverflow.com/questions/2003354/how-can-i-report-progress-from-a-background-task – Mark Feb 16 '10 at 20:02

3 Answers3

5

Obviously, the Future object would only be good for blocking and then receiving the result.

The Runnable or Callable object that you submit would either have to know how to provide this progress (percentage complete, count of attempts, status (enum?) etc) and provide that as an API call to the object itself, or posted in some lookup resource (in memory map or database if necessary). For simplicity I tend to like the object itself, especially since you're going to most likely need a handle (id) to lookup the object or a reference to the object itself.

This does mean that you have 3 threads operating. 1 for the actual work, 1 that is blocked while waiting for the result, and 1 that is a monitoring thread. The last one could be shared depending on your requirements.

Matt
  • 1,119
  • 7
  • 13
2

I was hoping that there was a standard concurrency framework way to stay updated on the progress of a long running task without requiring the client program to worry about orchestrating and synchronizing everything correctly. It seemed to me to that one could fathom an extended version of the Future<T> interface that would support: public short progress(); in addition to the usual isDone() and get() methods. Obviously the implementation of the progress() would then need to poll the object directly so maybe Future<T> would need to be specified as Future<T extends CanReportProgress> where CanReportProgress is the following interface:

public interface CanReportProgress {
    public short progress();
}

This begs the question of why one would bother to go through the Future object as opposed to calling the object itself to get the progress. I don't know. I'll have to give it more thought. It could be argued that it is closer to the current contract / semantics whereby the Callable object is not, itself, accessed again by the client programmer after the call to ExecutorService::submit / execute.

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • I don't know of anything out of the JDK box that would help you much other than to take the SwingWorker (part of 1.6 JDK) as an example of how a non-Swing version might look. It uses RunnableFuture and a getProgress() (with event notification)). This sounds like a solid start to me, since it's a known quantity and has been under development/test for years by greater minds. Best of luck. – Matt Feb 18 '10 at 15:34
  • 6
    Note that T in Future stands for the class of the return value. You can't access T until task done. So it's meaningless to make T extends CanReportProgress. – Anderson Sep 04 '13 at 09:26
2

In my case I passed a HashSet, with the Objects to process, as Parameter to the Method, wich was created as instance variable in the calling Class. When the asyncronous method removes the Objects after processing one can retrieve the size of the Map remaining in the calling Method. I thing in general passing Objects by Reference solves the Problem.

user771288
  • 21
  • 1
  • I was about to say the same thing in the answers. Just 1 more thing, in certain cases, the access of the method parameter should be controlled to avoid race conditions between multiple threads. Or a Map of threads and progress objects is good too. – PhoenixPerson May 16 '19 at 10:34