JavaRush /Java Blog /Random-IT /Cos'è Deadlock in Java?
Alexey Smirnov
Livello 29
Москва

Cos'è Deadlock in Java?

Pubblicato nel gruppo Random-IT
Livello di conoscenza richiesto per comprendere l'articolo: hai completato le missioni Java Syntax e Java Core e ora stai imparando il multithreading Java. Deadlock o deadlock in Java o deadlock è un errore che si verifica quando i thread hanno una dipendenza ciclica su una coppia di oggetti sincronizzati. Immaginate che un thread vada nel monitor oggetto xe l'altro nel monitor oggetto y. Se un thread in un oggetto xtenta di chiamare qualsiasi metodo sincronizzato sull'oggetto ye l'oggetto yallo stesso tempo tenta di chiamare qualsiasi metodo sincronizzato sull'oggetto x, i thread rimarranno bloccati in attesa. Cos'è lo stallo morto?  -1Di seguito è riportato un esempio tratto dal tutorial di Java Docs su un concetto come deadlock. Dove si verifica il blocco del thread qui?
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            @Override
            public void run() {
               // System.out.println("Thread 1");
                alphonse.bow(gaston);
               // System.out.println("Th: gaston bowed to alphonse");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
              //  System.out.println("Thread 2");
                gaston.bow(alphonse);
              //  System.out.println("2.gaston waiting alph bowed");
            }
        }).start();
    }
}
Ci sono due cose importanti da capire qui:
  1. Cosa fa esattamente ciascuno dei thread in esecuzione contemporaneamente?
  2. Quali serrature vengono utilizzate?
Cominciamo dalla fine. Diciamo che hai creato due oggetti della classe Friend: alphonsee gaston. Ognuno di loro ha la propria serratura. Quindi, ci sono due di queste serrature: gigolos e gastons. Quando viene immesso un metodo sincronizzato di un oggetto, il relativo blocco viene bloccato e quando si esce dal metodo viene rilasciato (o sbloccato). Ora riguardo ai thread. Chiamiamo il primo thread Alphonse(con la lettera maiuscola per distinguerlo dall'oggetto alphonse). Ecco cosa fa (chiamiamolo A, abbreviazione di Alphonse):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
Ed ecco cosa sta facendo il thread in questo momento Gaston:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Ora mettiamo insieme questi dati e otteniamo la risposta. I thread possono essere intrecciati (ovvero, i loro eventi si verificheranno) in ordini diversi. Un deadlock funzionerà, ad esempio, se l'ordine è il seguente:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
Cos'è lo stallo morto?  - 2
In questo caso, entrambi i thread sono bloccati e ciascuno attende che l'altro rilasci il blocco. Ma nessuno di loro lo farà, perché per farlo devono completare il loro metodo, che è bloccato da un altro thread. Quindi sono rimasti bloccati dove è successo deadlock. Tuttavia, è possibile anche un'altra trama, in cui uno dei fili avrà il tempo di completarsi prima che inizi il secondo:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
In questo caso non vi è alcun blocco reciproco dei thread. Ad esempio, è stato aggiunto un metodo che consente a un altro thread di avere il tempo di essere eseguito. Quando il risultato dipende dall'ordine degli eventi che si verificano simultaneamente (ordine pianificato o velocità di esecuzione), tale processo in russo viene chiamato race condition - "race condition". Non tutte le condizioni di gara causano potenzialmente una situazione di stallo, tuttavia, in base alla mia esperienza, solo le condizioni di gara causano situazioni di stallo. Inserito da: Dave Lillethun
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION