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.
引用java.util。我注意到并发包和未来的接口(除非我弄错了),启动一个冗长的任务并能够查询进度的能力只与SwingWorker实现类有关。
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.
在非gui、非swing应用程序(像一个控制台应用程序)中,是否有方法在后台启动一个冗长的任务,并允许其他线程检查进度?在我看来,似乎没有理由将这种功能局限于swing / GUI应用程序。否则,我认为唯一可用的选项是通过ExecutorService::submit,它返回一个未来的对象。然而,基础未来接口不允许监视进展。
3 个解决方案
#1
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.
您提交的Runnable或Callable对象要么必须知道如何提供这个进展(百分比完成、尝试计数、状态(enum?)等),并将其作为对对象本身的API调用,要么在某些查找资源(如有必要,在内存映射或数据库中)中发布。为了简单起见,我倾向于喜欢对象本身,特别是因为您很可能需要一个句柄(id)来查找对象或对象本身的引用。
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.
这意味着有3个线程在运行。对于实际的工作,1在等待结果时被阻塞,1是一个监视线程。最后一个可以根据您的需求进行共享。
#2
1
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.
在我的例子中,我传递了一个HashSet,将对象作为参数,作为方法的参数,在调用类中作为实例变量创建。当异步方法在处理后删除对象时,可以检索调用方法中剩余的映射的大小。通常通过引用传递对象可以解决这个问题。
#3
1
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
.
这就引出了一个问题:为什么一个人要费力地遍历未来的对象,而不是调用对象本身来获得进展。我不知道。我得再考虑一下。可以认为,它更接近于当前的契约/语义,即可调用对象本身不会在调用ExecutorService::submit / execute之后被客户机程序员再次访问。
#1
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.
您提交的Runnable或Callable对象要么必须知道如何提供这个进展(百分比完成、尝试计数、状态(enum?)等),并将其作为对对象本身的API调用,要么在某些查找资源(如有必要,在内存映射或数据库中)中发布。为了简单起见,我倾向于喜欢对象本身,特别是因为您很可能需要一个句柄(id)来查找对象或对象本身的引用。
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.
这意味着有3个线程在运行。对于实际的工作,1在等待结果时被阻塞,1是一个监视线程。最后一个可以根据您的需求进行共享。
#2
1
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.
在我的例子中,我传递了一个HashSet,将对象作为参数,作为方法的参数,在调用类中作为实例变量创建。当异步方法在处理后删除对象时,可以检索调用方法中剩余的映射的大小。通常通过引用传递对象可以解决这个问题。
#3
1
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
.
这就引出了一个问题:为什么一个人要费力地遍历未来的对象,而不是调用对象本身来获得进展。我不知道。我得再考虑一下。可以认为,它更接近于当前的契约/语义,即可调用对象本身不会在调用ExecutorService::submit / execute之后被客户机程序员再次访问。