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
   262   263   264   265   266   267   268   269   270   271   272