Koje načine borbe sa trkaćim uslovima niti, osim korišćenja ključne reči volatile, poznajete?
sobes.tech АИ
Одговор од АИ
Postoji nekoliko osnovnih pristupa za sinhronizaciju niti i sprečavanje trkaćih uslova u Androidu, pored volatile.
-
Korišćenje
synchronized: Blokira pristup kodu ili metodi za druge niti do završetka trenutne niti.// Sinhronizovana metoda synchronized void incrementCounter() { counter++; } // Sinhronizovani blok void updateData() { synchronized (this) { // ili drugi monitor objekat // kod koji zahteva sinhronizaciju } } -
Korišćenje klasa iz paketa
java.util.concurrent.locks: Nude fleksibilnije mehanizme zaključavanja odsynchronized.import java.util.concurrent.locks.ReentrantLock; private final ReentrantLock lock = new ReentrantLock(); void performLockedOperation() { lock.lock(); // Dobijanje zaključavanja try { // kod zaštićen zaključavanjem } finally { lock.unlock(); // oslobađanje zaključavanja (važno u finally) } } -
Korišćenje klasa iz paketa
java.util.concurrent.atomic: Nude atomarne operacije koje se izvršavaju kao celina bez prekida od strane drugih niti. Pogodno za jednostavne operacije nad primitivnim tipovima i referencama.import java.util.concurrent.atomic.AtomicInteger; private final AtomicInteger atomicCounter = new AtomicInteger(0); void incrementAtomicCounter() { atomicCounter.incrementAndGet(); // Atomno povećanje } -
Korišćenje bezbednih kolekcija: Kolekcije iz paketa
java.util.concurrent(npr.ConcurrentHashMap,CopyOnWriteArrayList) su dizajnirane za bezbednu upotrebu u višestrukim nitima bez eksplicitne sinhronizacije od strane programera.import java.util.concurrent.ConcurrentHashMap; import java.util.Map; private final Map<String, Integer> concurrentMap = new ConcurrentHashMap<>(); void updateMap(String key, Integer value) { concurrentMap.put(key, value); // bezbedna operacija upisa } -
Korišćenje
ThreadLocal: Omogućava kreiranje promenljive koja će imati zasebnu kopiju za svaku nit. Na taj način, svaka nit radi sa sopstvenim podacima, izbegavajući trke.private final ThreadLocal<Integer> threadLocalValue = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return 0; // početna vrednost za svaku nit } }; void processData() { int value = threadLocalValue.get(); value++; threadLocalValue.set(value); // postavljanje vrednosti za trenutnu nit }
Izbor metode zavisi od specifikacije zadatka, potrebe za zaključavanjem, tipa podataka i zahtevanog performansa.