Ang may-akda ng tala ay si Grzegorz Mirek, isang software developer mula sa Krakow (Poland). Nagsimula siyang umunlad sa Java mga 6 na taon na ang nakalilipas, habang nasa unibersidad pa, at mula noon ay walang sawang niyang pinapakintab ang kanyang mga kasanayan sa larangang ito. Siya ay partikular na interesado sa pagganap at pag-optimize ng JVM, na siyang pangunahing isinusulat niya sa kanyang blog .
Ang ilan sa mga pinakasikat na tanong sa panayam sa Java ay kinabibilangan ng: Ano ang pagkakaiba sa pagitan ng fail-fast at fail-safe iterator? Ang pinaka-pinasimpleng sagot dito ay: Ang isang fail-fast iterator ay nagtatapon ng isang ConcurrentModificationException kung ang koleksyon ay nagbabago sa panahon ng pag-ulit, ngunit ang isang fail-safe na iterator ay hindi. Bagama't mukhang makabuluhan ito, nananatiling hindi malinaw kung ano ang ibig sabihin ng tagapanayam sa fail-safe? Ang Mga Pagtutukoy ng Wika ng Java ay hindi tumutukoy sa terminong ito kaugnay ng mga iterator. Gayunpaman, mayroong apat na mapagkumpitensyang diskarte sa pagbabago.
Competitive na pagbabago
Una, tukuyin natin kung ano ang mapagkumpitensya (o parallel) na pagbabago. Sabihin nating mayroon tayong koleksyon at kapag aktibo ang iterator, may mga pagbabagong nagaganap na hindi nagmumula sa iterator na ito. Sa kasong ito, nakakakuha kami ng mapagkumpitensyang pagbabago. Bigyan kita ng isang simpleng halimbawa: sabihin nating mayroon tayong ilang mga thread. Ang unang thread ay umuulit, at ang pangalawang thread ay naglalagay o nag-aalis ng mga elemento mula sa parehong koleksyon. Gayunpaman, makakakuha tayo ng ConcurrentModificationException kapag tumatakbo sa isang single-threaded na kapaligiran: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
Fail-fast
Ang fragment ng code sa itaas ay isang halimbawa ng isang fail-fast iterator. Tulad ng nakikita mo, ang isang ConcurrentModificationException ay itinapon kapag sinusubukang kunin ang pangalawang elemento mula sa iterator . Paano malalaman ng isang iterator na ang koleksyon ay nabago mula noong ito ay nilikha? Halimbawa, maaaring may tatak ng petsa/oras ang koleksyon, sabihin lastModified . Kapag gumagawa ng iterator, dapat mong kopyahin ang field na ito at iimbak ito sa isang iterator object. Pagkatapos, sa tuwing tatawagin mo ang next() method , ihahambing mo lang ang lastModified value mula sa koleksyon sa kopya mula sa iterator. Ang isang katulad na diskarte ay ginagamit, halimbawa, sa pagpapatupad ng klase ng ArrayList . Mayroon itong instance variable modCount na nag-iimbak ng ilang beses na binago ang listahan:final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Mahalagang tandaan na ang mga fail-fast iterator ay gumagana sa isang best-of-breed na batayan, ibig sabihin ay walang garantiya na ang isang ConcurrentModificationException ay itatapon sa kaganapan ng isang kasabay na pagbabago. Kaya't hindi ka dapat umasa sa kanila - sa halip, dapat itong gamitin upang makakita ng mga error. Karamihan sa mga hindi kasabay na mga koleksyon ay nagbibigay ng mga hindi-mabilis na iterator.
Mahinang Consistency
Karamihan sa mga sabay-sabay na koleksyon sa java.util.concurrent package (tulad ng ConcurrentHashMap at karamihan sa Queue ) ay nagbibigay ng mahinang pare-parehong iterator. Ang kahulugan ng terminong ito ay napakahusay na ipinaliwanag sa dokumentasyon :- Maaari silang maiproseso nang sabay-sabay sa iba pang mga operasyon
- Hindi sila kailanman magtapon ng ConcurrentModificationException
- Ang mga ito ay ginagarantiyahan na tumawid sa mga umiiral na elemento sa oras na ang iterator ay ginawa nang eksaktong isang beses, at maaari (ngunit hindi kinakailangan na) ipakita ang mga kasunod na pagbabago.
GO TO FULL VERSION