Middle
Milyen alapvető szinkronizációs módszerek vannak Java-ban?
sobes.tech MI
Válasz az MI-től
A Java alapvető szinkronizációs módszerei:
-
A
synchronizedkulcsszó:- Olyan módszerek vagy kódblokkok szinkronizálására használják.
- A
synchronized-nel jelölt módszer blokkolja a hozzáférést az objektum példányához más szinkronizált módszerek számára ugyanazon az objektumon. synchronized (this): szinkronizálás a jelenlegi példányon.synchronized (ClassName.class): szinkronizálás a osztályon, blokkolva minden szál hozzáférését ehhez az osztályhoz.synchronized (object): szinkronizálás egy adott monitor objektumon.
class Counter { private int count = 0; // Szinkronizált metódus public synchronized void increment() { count++; } public void decrement() { // Szinkronizált blokk synchronized (this) { count--; } } } -
A
volatilekulcsszó:- Biztosítja a változó változásainak láthatóságát a szálak között.
- Nem garantálja összetett műveletek atomaritását (pl.
i++), csak olvasást és írást. - Osztálymezőkre alkalmazható.
class SharedData { volatile boolean flag = false; public void setFlag(boolean value) { flag = value; // A flag változása látható lesz más szálak számára } public boolean getFlag() { return flag; } } -
Explicit Lockok (Kifejezett zárolások):
- Rugalmasabb kontrollt biztosítanak a
synchronized-hez képest. - A
Lockinterfész és annak implementációi, például aReentrantLock. - Lehetővé teszik a tisztességes és tisztességtelen zárolási módok közötti választást, a zárolási állapot lekérdezését, a szál megszakítását zárolási várakozás közben.
- Egyértelmű
lock()ésunlock()hívásokat igényelnek. Fontos afinallyblokkban hívni azunlock()-ot.
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Resource { private final Lock lock = new ReentrantLock(); public void performAction() { lock.lock(); // Zárolás megszerzése try { // Kritikus szakasz System.out.println(Thread.currentThread().getName() + " zárolt"); Thread.sleep(100); // Munka szimulálása } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); // Zárolás feloldása System.out.println(Thread.currentThread().getName() + " feloldotta a zárolást"); } } } - Rugalmasabb kontrollt biztosítanak a
-
wait(),notify(),notifyAll():- Az
Objectosztály metódusai, amelyek a szálak közötti interakcióra szolgálnak, várva a monitor felszabadítására. wait(): felszabadítja a monitort és várakozó állapotba helyezi a szálat, amígnotify()vagynotifyAll()nem hívódik.notify(): felébreszt egy várakozó szálat ezen a monitoron.notifyAll(): felébreszti az összes várakozó szálat ezen a monitoron.- Ugyanazon monitor objektumon belül kell hívni őket, szinkronizált blokk vagy metódus részeként.
class ProducerConsumer { private final Object monitor = new Object(); private boolean isProduced = false; public void produce() throws InterruptedException { synchronized (monitor) { while (isProduced) { monitor.wait(); // Várakozás, amíg a fogyasztó elfogyasztja } // Gyártás System.out.println("Gyártott"); isProduced = true; monitor.notifyAll(); // Fogyasztók értesítése } } public void consume() throws InterruptedException { synchronized (monitor) { while (!isProduced) { monitor.wait(); // Várakozás, amíg a gyártó gyárt } // Fogyasztás System.out.println("Fogyasztott"); isProduced = false; monitor.notifyAll(); // Gyártók értesítése } } } - Az
Ezek a mechanizmusok alapvetőek a biztonságos több szálú kód létrehozásához Java-ban. A konkrét módszer kiválasztása a feladat jellemzőitől és a szinkronizáció feletti kontroll szintjétől függ.