Реци о стању трке (race condition) и како га избегнути у мулти-тред апликацијама.
sobes.tech АИ
Одговор од АИ
Stanje trke je greška u dizajnu višedretvenog sistema, pri čemu rezultat izvršavanja programa zavisi od reda izvršavanja delova koda od strane različitih niti. To se dešava kada više niti istovremeno pristupa zajedničkom promenljivom resursu bez odgovarajuće sinhronizacije.
Da bi se izbeglo stanje trke u Javi, koriste se sledeći pristupi:
-
Upotreba sinhronizovanih metoda i blokova:
class Counter { private int count = 0; // Sinhronizovana metoda public synchronized void increment() { count++; } // Sinhronizovani blok public void decrement() { synchronized (this) { count--; } } }Ključna reč
synchronizedgarantuje da samo jedna nit u isto vreme može izvršavati sinhronizovani kod za taj objekat (ili za klasu, ako je metoda statična). -
Upotreba klase
Lockiz paketajava.util.concurrent.locks:import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class SafeCounter { private int count = 0; private final Lock lock = new ReentrantLock(); public void increment() { lock.lock(); // Zauzimanje blokade try { count++; } finally { lock.unlock(); // Oslobađanje blokade } } }Lockpruža fleksibilnije mehanizme zaključavanja u poređenju sasynchronized. -
Upotreba atomskih promenljivih iz paketa
java.util.concurrent.atomic:import java.util.concurrent.atomic.AtomicInteger; class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // Atomarska operacija } }Atomarske promenljive pružaju atomarske operacije (npr. inkrement, dekrement) koje se izvršavaju kao celina i ne mogu biti prekinute drugim nitima.
-
Upotreba niti-bezbednih kolekcija iz paketa
java.util.concurrent: Na primer,ConcurrentHashMap,CopyOnWriteArrayList. Ove kolekcije su dizajnirane za sigurnu upotrebu u višedretvenom okruženju. -
Izbegavanje zajedničkog promenljivog stanja: Ako je moguće, podaci kojima pristupaju više niti treba da budu nepromenljivi (immutable) ili da budu odvojeni za svaku nit.
-
Upotreba
volatile: Ključna rečvolatilegarantuje vidljivost promena promenljive za sve niti, ali ne obezbeđuje atomarnost operacija (osim čitanja i pisanja primitivnih tipova, osim long i double, i referenci). Korisno je u kombinaciji sa drugim mehanizmima ili za jednostavne, nezavisne operacije stanja.class VolatileFlag { volatile boolean flag = false; // Garantovana vidljivost promena public void setFlag() { flag = true; } public boolean isFlag() { return flag; } }
Izbor odgovarajuće metode zavisi od konkretne situacije i zahteva za performanse i složenost koda.