ConcurrentHashMap и изменение его значения несколькими потоками - PullRequest
1 голос
/ 19 февраля 2020

У меня есть следующий сценарий ios:

Получить inputList:

ConcurrentHashMap<String, LinkedList<jobs>> inputList = new ConcurrentHashMap<>();

У меня есть два потока: Writer и Reader;

Поток Writer может добавить запись:

for (...){  // line 1
    if (!inputList.containsKey(jobListKey)) {    //line 2
        inputList.put(jobListKey, new LinkedList<jobs>());  //  LinkedList<jobs>  aka jobList   line 3
    } //  line 4
    inputList.get(jobListKey).addLast(new job(jobid)));  //line 5
}

Поток Reader обрабатывает это и удаляет из inputList

for (Iterator<Entry<String, LinkedList<jobs>>> it = inputList.entrySet().iterator(); it.hasNext(){  //line 7
      synchronized(processList) {  //line 8     
             if (!processList.contains(entry.getKey())) {    //line 9   
                LinkedList<jobs> jobList  = entry.getValue();   //line 9a
                doProcess(jobList);  //line 10    

                it.remove();  //line 12
             }
        } 
 }

Проблема, с которой я столкнулся (порядок по времени):

  1. line (3) Writer не нашел jobListKey, поэтому он создал новый (пустой) LinkedList<jobs> (jobList) и поместил в inputList;
  2. line (8) Считыватель находит новый jobListKey во время итерации, получает LinkedList<jobs> (на данном этапе пуст ) и начинает обработку, потому что он пуст, процесс завершился неудачей
  3. line (5) inputList получить последнюю запись добавить новое задание в LinkedList<jobs> (jobList)
  4. line (12) jobsList удаляется.

Есть три потенциальные проблемы:

  1. , когда Reader обрабатывает список заданий, возможно, он еще пуст.
  2. , пока Reader обрабатывает список заданий Writer может добавить больше новых заданий (jobbid) в строку 5
  3. После того, как Reader завершит работу с (строка 11) Writer также может добавить новое задание (в строке 5 ) и это задание не будет обработано и пропущено

Я попытался установить синхронизацию в Writer:

synchronized(inputList) {
    if (!inputList.containsKey(jobListKey)) {    //line 2
        inputList.put(jobListKey, new LinkedList<jobs>());  //  
               LinkedList<jobs>  aka jobList   line 3
    } //  line 4
    inputList.get(jobListKey).addLast(new job(jobid)));  //line 5
} 

К сожалению, он не работал с jobList.

Вопрос: Как я могу убедиться, что объект LinkedList, созданный в строке 3, будет синхронизирован / безопасен для потоков?

...