防止使用Java线程池时两次处理列表对象

时间:2018-10-25 08:10:07

标签: java threadpool threadpoolexecutor

假设我有10,000个对象的列表

ArrayList<String> al=new ArrayList<String>();  
al.add("1");  
al.add("2");
al.add("..");  
al.add("10000");

我想使用具有20个线程的线程池来处理10,000个对象。目标是确保我的程序一次准确地读取每个对象。

由于程序将不会标记已读取列表对象,因此我保证每个对象只能被处理一次吗?。

3 个答案:

答案 0 :(得分:0)

我有一个主意,也许确实很愚蠢。由于您仅尝试读取列表中的对象,因此如果应用此策略该怎么办。

  1. 列表中有10000个元素。
  2. 您有20个线程。
  3. 每个线程选择500个元素。
  4. 为每个线程分配一个整数ID,例如1到20。
  5. 每个线程根据元素的整数ID访问元素。
  6. 就像线程1访问0-499。
  7. 类似地,从500-999线程2访问,依此类推。
  8. 这将确保您不会被多个线程读取任何元素。
  9. 这里有一个假设,即所有线程将对元素执行类似的处理。

在另一种方法中,您可以做的是,创建一个同步集,每次选择一个元素时,检查索引是否存在于集合中,如果不存在,则选择该元素并将其索引插入到索引中。组。这样,您将不会两次选择元素。

答案 1 :(得分:0)

您可以使用以下代码:

ExecutorService executorService = Executors.newFixedThreadPool(20);

executorService.execute(new Runnable() {
    public void run() {
        //add item in here and remember using sync data
    }
});
executorService.shutdown();

答案 2 :(得分:0)

将列表分为20部分:

Map<Integer, List<String>> mapList = al.stream().collect(Collectors.groupingBy(i -> i.hashCode() % 20));