2011-05-24 74 views
3

我正在寻找一个简单的对象,它将保存我的工作线程,我需要它不会限制线程的数量,并且不会使它们的活动时间超过所需的时间。 但我需要它有类似于ExecutorService.shutdown(); 的方法(等待所有的活动线程来完成,但不接受任何新的)在java中的“简单”线程池

所以也许一个线程池是不是我所需要的,所以我会爱向正确的方向推进。 (因为他们是为了保持线程活着)

进一步澄清意图:

每个线程是一个文件的上传,而我还有一个过程,修改文件,但它等待文件没有任何上传。通过加入每个线程。所以当它们保持活动时,它会锁定这个过程。 (每个线程都将自己添加到创建时的特定文件的列表中,所以我只加入()线程以上载特定文件)

回答

0

是否有您不想重用线程的原因?在我看来,最简单的事情就是使用ExecutorService,并让它重用线程。

+0

每个线程都是一个文件的上传,而我有另一个修改文件的进程,但它等待文件没有任何上传。通过加入每个线程。所以当他们保持活着时,它会锁定这个过程。 (每个线程都将自己添加到创建时的特定文件的列表中,所以我只加入()线程来上传特定文件) – Bg1987 2011-05-24 17:01:42

+2

您正在合并两个概念:线程和任务。任务是“上传这个文件”,线程是完成任务的可重用资源。任务(可上传的Runnable)可以在没有在线程上调用join()的情况下发出“其他进程”的信号。 “其他流程”究竟如何接收这些信号? – 2011-05-24 17:38:08

6

一种方法可以使用CallableFuture,该方法返回已完成上载的File对象。然后将Future传递到另一个Callable,该Callable检查Future.isDone()并旋转,直到它返回true,然后对文件执行任何您需要的操作。您的使用案例不是唯一的,并且非常适合java.util.concurrentpackage capabilities

一个有趣的类是ExecutorCompletionServiceclass它完全按照你想要的等待结果然后进行额外的计算。

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.niopackage并阅读有关非阻塞I/O。