Middle
Kokie yra pagrindiniai sinchronizacijos būdai Java?
sobes.tech AI
Atsakymas iš AI
Pagrindiniai sinchronizacijos būdai Java:
-
synchronizedraktinis žodis:- Naudojamas metodų arba kodo blokų sinchronizavimui.
synchronizedžymėtas metodas blokuoja prieigą prie objekto instancijos kitiems sinchronizuotiems to paties objekto metodams.synchronized (this): sinchronizacija pagal esamą objekto instanciją.synchronized (ClassName.class): sinchronizacija pagal klasę, blokuoja prieigą visiems srautams, dirbantiems su šiuo klasiu.synchronized (object): sinchronizacija pagal konkretų monitoriaus objektą.
class Counter { private int count = 0; // Sinchronizuotas metodas public synchronized void increment() { count++; } public void decrement() { // Sinchronizuotas blokas synchronized (this) { count--; } } } -
volatileraktinis žodis:- Garantuoja kintamojo matomumą tarp srautų.
- Neužtikrina sudėtingų operacijų atomingumo (pvz.,
i++), tik skaitymą ir rašymą. - Taikomas klasės laukams.
class SharedData { volatile boolean flag = false; public void setFlag(boolean value) { flag = value; // Flag keitimas tampa matomas kitiems srautams } public boolean getFlag() { return flag; } } -
Išorinės užrakinimo priemonės (Explicit Locks):
- Siūlo lankstesnę kontrolę nei
synchronized. Locksąsaja ir jos įgyvendinimai, pvz.,ReentrantLock.- Leidžia pasirinkti sąžiningą ir nesąžiningą užrakinimo režimą, gauti užrakinimo būseną, nutraukti srautą užrakinimo metu.
- Reikalauja aiškaus
lock()irunlock()iškvietimo. Svarbu naudotifinallyblokąunlock()iškvietimui.
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(); // Užrakinimo gavimas try { // Kritinė sekcija System.out.println(Thread.currentThread().getName() + " užėmė užraktą"); Thread.sleep(100); // Darbo imitacija } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); // Užrakinimo atlaisvinimas System.out.println(Thread.currentThread().getName() + " atlaisvino užraktą"); } } } - Siūlo lankstesnę kontrolę nei
-
wait(),notify(),notifyAll():Objectklasės metodai, naudojami srautų sąveikai, laukiančioms monitoriaus atlaisvinimo.wait(): atlaisvina monitorių ir perveda srautą į laukimo būseną ikinotify()arnotifyAll()iškvietimo.notify(): pažadina vieną laukiančią srautą.notifyAll(): pažadina visus laukiančius srautus.- Juos reikia iškviesti to paties monitoriaus sinchronizuotame bloke ar metode.
class ProducerConsumer { private final Object monitor = new Object(); private boolean isProduced = false; public void produce() throws InterruptedException { synchronized (monitor) { while (isProduced) { monitor.wait(); // Laukia, kol vartotojas suvalgys } // Gamina System.out.println("Gamyba"); isProduced = true; monitor.notifyAll(); // Praneša vartotojams } } public void consume() throws InterruptedException { synchronized (monitor) { while (!isProduced) { monitor.wait(); // Laukia, kol gamintojas pagamins } // Vartoja System.out.println("Vartoja"); isProduced = false; monitor.notifyAll(); // Praneša gamintojams } } }
Šie mechanizmai yra pagrindas kurti saugų daugiagijų kodą Java. Pasirinkimas priklauso nuo užduoties ypatybių ir reikiamos kontrolės lygio.