Pasakykite apie lenktynių būseną (race condition) ir kaip jos galima išvengti daugialypėse programose.
sobes.tech AI
Atsakymas iš AI
Darbų būklė yra daugiagijinio sistemos projektavimo trūkumas, kai programos vykdymo rezultatas priklauso nuo to, kaip tvarkomi kodo dalys skirtingų sruogų. Tai įvyksta, kai keli sruogos vienu metu prieina prie bendro kintamojo ištekliaus be tinkamos sinchronizacijos.
Norint išvengti lenktynių būsenos Java, naudojami šie požiūriai:
-
Naudojant sinchronizuotas metodus ir blokus:
class Counter { private int count = 0; // Sinchronizuotas metodas public synchronized void increment() { count++; } // Sinchronizuotas blokas public void decrement() { synchronized (this) { count--; } } }Raktinis žodis
synchronizedužtikrina, kad tik viena sruoga vienu metu gali vykdyti sinchronizuotą kodą šiam objektui (arba klasei, jei metodas statinis). -
Naudojant
Lockklasę išjava.util.concurrent.lockspaketo: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(); // Užrakinimo įgijimas try { count++; } finally { lock.unlock(); // Atskleidimo } } }Locksuteikia lankstesnius užrakinimo mechanizmus neisynchronized. -
Naudojant atominius kintamuosius iš
java.util.concurrent.atomicpaketo:import java.util.concurrent.atomic.AtomicInteger; class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // Atominis veiksmas } }Atominiai kintamieji teikia atominius veiksmus (pvz., didinimą, mažinimą), kurie vykdomi kaip vienas vienetas ir negali būti nutraukti kitų sruogų.
-
Naudojant saugias sruogų kolekcijas iš
java.util.concurrentpaketo: Pavyzdžiui,ConcurrentHashMap,CopyOnWriteArrayList. Šios kolekcijos sukurtos saugiam naudojimui daugiagijiniame aplinkoje. -
Vengiant bendro kintamojo būsenos: Jei įmanoma, duomenys, prieinami kelioms sruogoms, turėtų būti nekintami (immutable) arba atskiri kiekvienai sruogai.
-
Naudojant
volatile: Raktinis žodisvolatileužtikrina, kad kintamojo pakeitimai būtų matomi visoms sruogoms, tačiau nesuteikia operacijų atomingumo (išskyrus paprastų primityvių tipų skaitymą ir rašymą, išskyrus long ir double, taip pat nuorodų). Tai naudinga kartu su kitais mechanizmais arba paprastoms, nepriklausomoms nuo būsenos operacijoms.class VolatileFlag { volatile boolean flag = false; // Pakeitimų matomumas garantuotas public void setFlag() { flag = true; } public boolean isFlag() { return flag; } }
Pasirinkimas priklauso nuo konkrečios situacijos ir našumo bei kodo sudėtingumo reikalavimų.