Предотвращение двойной обработки объектов списка при использовании пула потоков Java - PullRequest
0 голосов
/ 25 октября 2018

Допустим, у меня есть список из 10000 объектов

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

Я хочу обработать 10000 объектов, используя пул потоков с 20 потоками. Цель состоит в том, чтобы моя программа считывала каждый объект ровно один раз.

Поскольку программа не будет отмечать, что объект списка был прочитан, я гарантирую, что каждый объект будет обработан только один раз?.

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

U можете использовать этот код:

ExecutorService executorService = Executors.newFixedThreadPool(20);

executorService.execute(new Runnable() {
    public void run() {
        //add item in here and remember using sync data
    }
});
executorService.shutdown();
0 голосов
/ 25 октября 2018

Разделите список на 20 частей:

Map<Integer, List<String>> mapList = al.stream().collect(Collectors.groupingBy(i -> i.hashCode() % 20));
0 голосов
/ 25 октября 2018

У меня есть идея, и она действительно может быть глупой.Поскольку вы пытаетесь только читать объекты в списке, как насчет того, чтобы применить эту стратегию.

  1. В вашем списке 10000 элементов.
  2. У вас 20 потоков.
  3. Каждый поток выбирает 500 элементов.
  4. Каждому потоку присваивается целочисленный идентификатор, например от 1 до 20.
  5. Каждый поток обращается к элементам на основе своего целочисленного идентификатора.
  6. Аналогично доступу потока 1 от 0-499.
  7. Аналогично доступу потока 2 с 500-999 и т. Д.
  8. Это гарантирует, что ни один элемент не будет прочитан несколькими потоками.
  9. Здесь предполагается, что все потоки будут выполнять одинаковый тип обработки элементов.

И в другом подходе вы можете создать Синхронизированный набор и каждый раз, когда выбираете элемент, проверьте, присутствует ли индекс в наборе или нет, выберите элемент и вставьте его индекс в набор.Таким образом, вы не выберете элемент дважды.

...