2015-09-10 5 views
4

Я изучаю потоки Java и хочу знать, есть ли что-то не так с этим кодом. Поскольку я использую параллельный поток, я использовал ConcurrentHashMap.Концепция параллельных потоков

class Person { 
    private String name; 

    public String getName() { 
     return this.name; 
    } 
} 

и

ConcurrentHashMap<Integer, Person> map = <Mapping of id to Person> 
List<Integer> list = <list of Id> 

list = list.parallelStream() 
     .filter(id -> map.containsKey(id) 
         && !Strings.isNullOrEmpty(map.get(id).getName())) 
     .collect(Collectors.toList()); 
+0

«если что-то не так с этим кодом» вы получаете какие-либо ошибки/неправильные результаты? – Pshemo

+0

Мне просто интересно, вызовет ли доступ к карте в этом контексте любые нежелательные результаты. – user3704576

+0

Это может зависеть от того, что вы подразумеваете под * нежелательным *. Также, что вы подразумеваете под доступом? Может ли другой поток модифицировать эту карту при ее потоке? Может ли эта модификация игнорироваться потоком? – Pshemo

ответ

5

Если карта активно обновляется, у вас может быть гонка между containsKey и get. Вместо этого вы могли бы написать что-то вроде

list.parallelStream() 
    .filter(id -> { 
     Person person = map.get(id); 
     return person != null && !Strings.isNullOrEmpty(person.getName()); 
    }) 
    .collect(Collectors.toList()); 

Использование parallelStream не имеет ничего общего с этим - это прекрасно. Он выполняет два отдельных вызова на ConcurrentMap по одному и тому же ключу и ожидает, что они будут иметь согласованные результаты.

+1

Да, * check-then-act * antipattern. Вы также можете использовать либо. .Filter (id -> Optional.ofNullable (map.get (id)). Map (Person :: getName) .filter (s ->! S.isEmpty()). IsPresent()) ' или немного более короткое '.filter (id ->! Optional.ofNullable (map.get (id)). map (Person :: getName) .orElse (" "). isEmpty())' хотя я предпочитаю первый вариант для ясность ... В любом случае методы сторонней библиотеки, такие как 'Strings.isNullOrEmpty', устарели. – Holger

2

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

В вашем случае будет работать обычный HashMap, потому что вы только запрашиваете карту. Как-то никто обновляет список во время потоковой передачи, у вас нет многопоточной конкуренции.

Смежные вопросы