JavaRush /Блоги Java /Random-TG /Қиссаи ду итератор: Стратегияҳои тағир додани рақобат дар...

Қиссаи ду итератор: Стратегияҳои тағир додани рақобат дар Java

Дар гурӯҳ нашр шудааст
Муаллифи ёддошт Гжегож Мирек, таҳиягари нармафзор аз Краков (Польша) мебошад. Вай тақрибан 6 сол пеш, ҳанӯз дар донишгоҳ таҳсил карданро дар Ёва оғоз карда буд ва аз он вақт инҷониб маҳорати худро дар ин самт беист сайқал медиҳад. Вай махсусан ба иҷрои JVM ва оптимизатсия таваҷҷӯҳ дорад, ки он чизест, ки ӯ асосан дар блоги худ менависад .
Қиссаи ду итератор: Стратегияҳои тағир додани рақобат дар Java - 1
Баъзе аз маъмултарин саволҳои мусоҳибаи Java иборатанд аз: Фарқи байни итераторҳои зуд ноком ва аз нокомии бехатар чӣ гуна аст? Ҷавоби соддатарин ба ин ин аст: Итератори зуд-зуд ConcurrentModificationException-ро мепартояд, агар коллексия ҳангоми итератсия тағир ёбад, аммо итератори аз хатогӣ бехатар ин тавр намекунад. Гарчанде ки ин хеле пурмаъно ба назар мерасад, аммо маълум нест, ки мусоҳиба аз нокомӣ чӣ маъно дорад? Мушаххасоти забони Java ин истилоҳро нисбат ба итераторҳо муайян намекунад. Аммо, чор стратегияи тағир додани рақобат вуҷуд дорад.

Тағироти рақобат

Аввалан, биёед муайян кунем, ки тағйироти рақобатпазир (ё мувозӣ) чист. Фарз мекунем, ки мо коллексия дорем ва вақте ки итератор фаъол аст, баъзе тағиротҳо ба амал меоянд, ки аз ин итератор намеоянд. Дар ин ҳолат, мо тағйироти рақобатпазир мегирем. Ичозат дихед ба шумо як мисоли оддй дихам: бигуем, ки мо якчанд ришта дорем. Риштаи якум такрор мешавад ва риштаи дуюм элементҳоро аз як коллексия дохил мекунад ё хориҷ мекунад. Бо вуҷуди ин, мо метавонем ConcurrentModificationException ҳангоми кор дар муҳити як ришта ба даст орем:
List<String> cities = new ArrayList<>();
cities.add(Warsaw);
cities.add(Prague);
cities.add(Budapest);

Iterator<String> cityIterator = cities.iterator();
cityIterator.next();
cities.remove(1);
cityIterator.next(); // генерирует ConcurrentModificationException

Муваффақият - зуд

Фрагменти codeи дар боло овардашуда намунаи итератори зуд ноком аст . Тавре ки шумо мебинед, ҳангоми кӯшиши гирифтани унсури дуюм аз итератор як ConcurrentModificationException партофта шуд . Итератор аз куҷо медонад, ки коллексия аз замони офарида шуданаш тағир дода шудааст? Масалан, коллексия метавонад мӯҳри сана/вақт дошта бошад, мегӯянд lastModified . Ҳангоми сохтани итератор, шумо бояд ин майдонро нусхабардорӣ кунед ва онро дар an objectи итератор нигоҳ доред. Сипас, ҳар дафъае, ки шумо ба усули next() занг мезанед, шумо танҳо арзиши LastModified аз коллексияро бо нусхаи итератор муқоиса мекунед . Равиши хеле шабеҳ, масалан, дар татбиқи синфи ArrayList истифода мешавад . Он дорои як тағирёбандаи мисоли modCount , ки миқдори маротиба тағир додани рӯйхатро нигоҳ медорад:
final void checkForComodification() {
   if (modCount != expectedModCount)
       throw new ConcurrentModificationException();
}
Қайд кардан муҳим аст, ки итераторҳои ноком дар асоси беҳтарини зот кор мекунанд, яъне ҳеҷ кафолате нест, ки ConcurrentModificationException дар сурати тағир додани ҳамзамон партофта мешавад. Аз ин рӯ, шумо набояд ба онҳо такя кунед - балки онҳо бояд барои ошкор кардани хатогиҳо истифода шаванд. Аксари коллексияҳои ҳамзамон итераторҳои нокомро таъмин мекунанд .

Мутобиқати суст

Аксари коллексияҳои ҳамзамон дар бастаи java.util.concurrent (ба монанди ConcurrentHashMap ва аксари Queue ) итераторҳои сусти мувофиқро таъмин мекунанд. Маънои ин истилоҳ дар ҳуҷҷатҳо хеле хуб шарҳ дода шудааст :
  • Онҳоро ҳамзамон бо дигар амалиётҳо коркард кардан мумкин аст
  • Онҳо ҳеҷ гоҳ ConcurrentModificationException- ро намепартоянд
  • Ба онҳо кафолат дода мешавад, ки унсурҳои мавҷударо дар лаҳзаи эҷоди итератор маҳз як маротиба гузаранд ва метавонанд (вале талаб карда намешаванд) тағироти минбаъдаро инъикос кунанд.

Сурати лаҳзае

Бо ин стратегия, итератор бо ҳолати коллексия дар вақти офариниш алоқаманд аст - ин акси коллексия аст. Ҳама гуна тағйироте, ки ба коллексияи аслӣ ворид карда мешавад, боиси эҷоди versionи нави сохтори асосии маълумот мегардад. Ин тасвири моро бетағйир мегузорад, аз ин рӯ он тағиротро дар коллексия, ки пас аз эҷоди итератор ба амал омадааст, инъикос намекунад. Ин техникаи хуби нусхабардорӣ дар навиштан (COW) мебошад . Он масъалаи тағироти ҳамзамонро комилан ҳал мекунад, бинобар ин бо ин равиш ConcurrentModificationException тавлид намешавад. Илова бар ин, итераторҳо амалиётҳоеро, ки элементҳоро тағир медиҳанд, дастгирӣ намекунанд. Маҷмӯаҳои нусхабардорӣ ба навиштан одатан барои истифода хеле гарон ҳастанд, аммо истифодаи онҳо маъно дорад, агар тағирот нисбат ба гузариши итератор камтар ба амал ояд. Намунаҳо синфҳои CopyOnWriteArrayList ва CopyOnWriteArraySet мебошанд .

Рафтори номуайян

Шумо метавонед дар намудҳои коллексияи меросӣ ба монанди Vector ва Hashtable бо рафтори номуайян дучор шавед . Ҳарду итераторҳои стандартии зуд ноком доранд, аммо илова бар ин, онҳо имкон медиҳанд, ки татбиқи интерфейси Enumeration истифода шаванд ва онҳо дар сурати тағир додани ҳамзамон чӣ гуна рафтор карданро намедонанд. Шумо метавонед бо баъзе унсурҳои такроршаванда ё нопадидшуда дучор шавед, ё ҳатто баъзе истисноҳои аҷиб. Беҳтараш бо онҳо бозӣ накунед!
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION