2013-11-03 12 views
3

我有下面的代码片段,我想知道如果在循环中提交Runnable的实例是在线程池上运行任务的好习惯。将Runnable提交到循环中的线程池是否是好习惯?

我需要访问到循环这是我的推理以外的名单。这是伪代码,所以我真正的代码使用ConcurrentHashMap,消除了线程问题。如果这是不好的做法,有没有人有更好的建议?我试图把它分成另一个班级,但遇到了我的外部列表问题。

我遇到了麻烦,知道何时清除内存中的列表,我无法知道线程何时完成。

public void startJob() { 
    int threads = Runtime.getRuntime().availableProcessors(); 
    ExecutorService exec = Executors.newFixedThreadPool(threads); 

    final List<ImportTask> importTasks = session.createCriteria(ImportTask.class).list(); 
    final List<Object> objs = new ArrayList<>(); 

    int count = 0; 

    for (ImportTask importTask : importTasks) { 
     exec.submit(new Runnable() { 
      @Override 
      public void run() { 
       count++; 

       if(objs.contains(importTask) { 
        obj = objs.get(importTask.indexOf(importTask)); 
       } else { 
        Object obj = new Object(); 
        objs.add(obj); 
        session.save(obj); 
       } 


       if(count % 50 = 1000) { 
        session.flush(); 
        session.commit(); 
       } 
      } 
     } 
    } 
} 
+4

这个问题似乎是题外话题,因为它是关于审查(推测工作)的代码。请在http://codereview.stackexchange.com上提问 – Bohemian

+0

@Bohemian这个问题是完全关于主题,我没有必要发布我的确切对象。我只是问,如果循环使用可运行的ExecutorService是一种好的做法。我在当前的代码中使用这个循环,但担心问题。 –

+0

如果可能的话,在run()方法内部编写循环显然会更好。使用ExecutorService作为* ersatz *'for'循环肯定不是好习惯。 – EJP

回答

3

Runnable的实例提交给线程池是实现任务并发执行的完美有效方法。

要知道每个任务何时完成,请保留由ExecutionService.submit()返回的Future对象的列表。

Future<?> future = exec.submit(new Runnable() { 
... 
futures.add(future); 

最后得到每个未来使用阻止Future.get()的结果。

正如其他答案所示,您也可以使用ExecutorService.invokeAll()。不同的是,该方法只需要Callable而不是Runnable,必须一次提交所有任务,并且该方法将等待,直到最后一个任务终止。

进一步的步骤,这将使你的代码更整洁是使你的任务(ImportTask实施Callable接口(和call法)和它的计算。如果您需要将值传递给任务,例如您的objs列表,则可以通过ImportTask的构造函数来完成。

+0

感谢您的回复。使用提交超过pasha701的使用invokeAll的答案有什么区别? –

+0

请参阅更新回答以获取方法比较 – Boj

1

要知道所有线程何时完成,您可以使用“ExecutorService.invokeAll”而不是“submit”。

+0

invokeAll和Wlll对未来的建议有什么区别? –

+0

如果你制作“未来 future = exec.submit(新的Runnable()..”,下一个语句将是“future.get()”,当前线程将等待Runnable结束,只有一个线程将运行使用“invokeAll “许多线程都运行,当前线程只会在所有线程结束时才会继续。 – pasha701

相关问题