Page 267 - 6253
P. 267
потоків та фіксовану кількість записуючих потоків. За замовчуванням допускається
до 16 паралельно виконуваних записуючих потоків. Якщо запис в колекцію
одночасно виконується більше ніж в 16-ти потоках, то інші потоки тимчасово
блокуються. Під час створення у конструкторі можна вказати і більшу кількість
потоків, проте на практиці даної кількості цілком вистачає.
У класах ConcurrentHashMap та ConcurrentSkipListMap визначено корисні
методи для виконання атомарних операцій створення і видалення взаємозв’язків між
ключами і значеннями, які також називаються асоціаціями. Зокрема, метод
putIfAbsent() атомарно додає нову асоціацію, якої не було раніше. Така можливість
дозволяє організувати кеш, який буде доступний для декількох потоків, проте тільки
один з них зможе додавати елементи у кеш в будь-який момент часу.
cache.putIfAbsent(key, value);
Зворотну атомарну операцію можна виконати за допомогою методу remove(),
який, у свою чергу викликає метод removeIfPresent().
cache.remove(key, value);
І, нарешті, для модифікації елемента в потокобезпечній колекції
використовується метод replace(), в який передається ключ елемента та його нове
значення.
cache.replace(key, oldValue, newValue);
Класи CopyOnWriteArrayList та CopyOnWriteArraySet представляють собою
потокобезпечні колекції, в яких при будь-яких змінах створюється копія базового
масиву. Такий підхід є зручним у випадку, якщо кількість потоків, що виконують
обхід колекції, значно перевищує кількість потоків, що змінюють її стан. Коли
відбувається створення ітератора такої колекції, то він містить посилання на
поточний масив. Якщо в майбутньому значення в масиві зміняться, то ітератор як і
раніше буде посилатися на стару копію масиву, а поточний масив колекції буде
замінений новим. Як наслідок, «старий» ітератор зберігає узгоджений (хоча й
потенційно застарілий) стан колекції, що не вимагає додаткових затрат на
синхронізацію.
Більше інформації по приведеній тематиці можна знайти в джерелах [8-25].
266