一种方法可以使用Callable
和Future
,该方法返回已完成上载的File
对象。然后将Future
传递到另一个Callable
,该Callable
检查Future.isDone()
并旋转,直到它返回true
,然后对文件执行任何您需要的操作。您的使用案例不是唯一的,并且非常适合java.util.concurrent
package capabilities。
一个有趣的类是ExecutorCompletionService
class它完全按照你想要的等待结果然后进行额外的计算。
CompletionService使用 提供的Executor执行任务。 本课安排提交的 任务完成后,放在 的队列中,可以使用take。 类的重量足够轻以便当 处理任务组时,适合于暂时使用 。
应用实例:假设你有一组求解的一定问题, 每区选出某种类型 结果的价值,并想运行它们 同时,处理结果他们每个人说的 返回非空值 ,在某些方法中使用(Result r)。 你可以这样写:
void solve(Executor e, Collection<Callable<Result>> solvers)
throws InterruptedException, ExecutionException
{
CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers) { ecs.submit(s); }
int n = solvers.size();
for (int i = 0; i < n; ++i)
{
Result r = ecs.take().get();
if (r != null) { use(r); }
}
}
你不想无限制的ExecutorService的
你几乎要允许无界线程池,因为他们实际上可能会限制你的应用程序的性能如果线程数量失控。
您的域受到磁盘或网络I/O或两者的限制,因此一个小线程池就足够了。您不想尝试从每个连接的线程读取数百或数千个传入连接。
您的解决方案的一部分(如果您收到的并发上传数量较少)是调查java.nio
package并阅读有关非阻塞I/O。
每个线程都是一个文件的上传,而我有另一个修改文件的进程,但它等待文件没有任何上传。通过加入每个线程。所以当他们保持活着时,它会锁定这个过程。 (每个线程都将自己添加到创建时的特定文件的列表中,所以我只加入()线程来上传特定文件) – Bg1987 2011-05-24 17:01:42
您正在合并两个概念:线程和任务。任务是“上传这个文件”,线程是完成任务的可重用资源。任务(可上传的Runnable)可以在没有在线程上调用join()的情况下发出“其他进程”的信号。 “其他流程”究竟如何接收这些信号? – 2011-05-24 17:38:08