Sobes.tech
Middle

Millised on Java põhitehnoloogiad sünkroniseerimiseks?

sobes.tech AI

Vastus AI-lt

Java põhitehnoloogiad sünkroniseerimise meetodid:

  1. synchronized märksõna:

    • Kasutatakse meetodite või koodiblokkide sünkroniseerimiseks.
    • synchronized märgitud meetod blokeerib juurdepääsu objekti eksemplarile teiste selle sama objekti sünkroniseeritud meetodite jaoks.
    • synchronized (this): sünkroniseerimine praeguse objekti eksemplari järgi.
    • synchronized (ClassName.class): sünkroniseerimine klassi järgi, blokeerib juurdepääsu kõigile voogudele, mis töötavad selle klassiga.
    • synchronized (object): sünkroniseerimine konkreetse monitoori objekti järgi.
    class Counter {
        private int count = 0;
    
        // Sünkroniseeritud meetod
        public synchronized void increment() {
            count++;
        }
    
        public void decrement() {
            // Sünkroniseeritud plokk
            synchronized (this) {
                count--;
            }
        }
    }
    
  2. volatile märksõna:

    • Tagab muutujate nähtavuse voogude vahel.
    • Ei taga keerukate operatsioonide (nt i++) atomilisust, vaid ainult lugemist ja kirjutamist.
    • Rakendub klassi väljadele.
    class SharedData {
        volatile boolean flag = false;
    
        public void setFlag(boolean value) {
            flag = value; // Muutuse nähtavus teiste voogude jaoks
        }
    
        public boolean getFlag() {
            return flag;
        }
    }
    
  3. Välised lukud (Explicit Locks):

    • Pakuvad paindlikumat kontrolli võrreldes synchronized-ga.
    • Lock liides ja selle rakendused, näiteks ReentrantLock.
    • Annab võimaluse valida aus ja ebaaus lukustusrežiim, saada lukustamise olekut, katkestada voog lukustamise ajal.
    • Nõuab selget lock() ja unlock() väljakutset. Oluline on kasutada finally plokki unlock()-i jaoks.
    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(); // Lukustuse saamine
            try {
                // Kriitiline sektsioon
                System.out.println(Thread.currentThread().getName() + " omandas lukku");
                Thread.sleep(100); // Töö imitatsioon
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock(); // Lukust vabastamine
                System.out.println(Thread.currentThread().getName() + " vabastas lukku");
            }
        }
    }
    
  4. wait(), notify(), notifyAll():

    • Object klassi meetodid, mida kasutatakse voogude vaheliseks suhtluseks, mis ootavad monitori vabastamist.
    • wait(): vabastab monitori ja paneb voogu ootama kuni notify() või notifyAll() kutsutakse.
    • notify(): äratab ühe ootava voogu.
    • notifyAll(): äratab kõik ootavad voogud.
    • Neid tuleb kutsuda samas sünkroniseeritud plokis või meetodis selle sama monitori objekti jaoks.
    class ProducerConsumer {
        private final Object monitor = new Object();
        private boolean isProduced = false;
    
        public void produce() throws InterruptedException {
            synchronized (monitor) {
                while (isProduced) {
                    monitor.wait(); // Ootame kuni tarbija sööb
                }
                // Toote valmistamine
                System.out.println("Toodetud");
                isProduced = true;
                monitor.notifyAll(); // Teavitame tarbijaid
            }
        }
    
        public void consume() throws InterruptedException {
            synchronized (monitor) {
                while (!isProduced) {
                    monitor.wait(); // Ootame kuni tootja toodab
                }
                // Tarbimine
                System.out.println("Tarbitud");
                isProduced = false;
                monitor.notifyAll(); // Teavitame tootjaid
            }
        }
    }
    

Need mehhanismid on aluseks turvalise mitmevoogulise koodi loomisel Java-s. Valik sõltub ülesande spetsiifikast ja nõutavast kontrollitasemest.