387 Stimmen

Warum ein ReentrantLock verwenden, wenn man synchronized(this) verwenden kann?

Ich versuche zu verstehen, warum die Sperre bei Gleichzeitigkeit so wichtig ist, wenn man die synchronized (this) . In dem Dummy-Code unten kann ich beides tun:

  1. die gesamte Methode synchronisieren oder den gefährdeten Bereich synchronisieren ( synchronized(this){...} )
  2. ODER sperren Sie den anfälligen Codebereich mit einem ReentrantLock.

Código:

    private final ReentrantLock lock = new ReentrantLock(); 
    private static List<Integer> ints;

    public Integer getResult(String name) { 
        .
        .
        .
        lock.lock();
        try {
            if (ints.size()==3) {
                ints=null;
                return -9;
            }   

            for (int x=0; x<ints.size(); x++) {
                System.out.println("["+name+"] "+x+"/"+ints.size()+". values >>>>"+ints.get(x));
            }

        } finally {
            lock.unlock();
        } 
        return random;
}

3voto

Dhaval D Punkte 808

Eine Sache, die Sie beachten sollten, ist:

Der Name ' ReentrantLock ' gibt eine falsche Nachricht über andere Verriegelungsmechanismen aus, dass sie nicht re-entrant sind. Das ist nicht wahr. Eine über 'synchronized' erworbene Sperre ist in Java ebenfalls reentrant.

Der Hauptunterschied besteht darin, dass "synchronized" eine intrinsische Sperre verwendet (eine, die jedes Objekt hat), während die Lock API dies nicht tut.

0voto

Solubris Punkte 3503

Ich denke, die Methoden wait/notify/notifyAll gehören nicht in die Klasse Object, da sie alle Objekte mit Methoden verunreinigen, die selten verwendet werden. Sie machen viel mehr Sinn in einer eigenen Lock-Klasse. Unter diesem Gesichtspunkt ist es vielleicht besser, ein Werkzeug zu verwenden, das explizit für diese Aufgabe entwickelt wurde - also ReentrantLock.

-1voto

RonTLV Punkte 2367

Gehen wir davon aus, dass dieser Code in einem Thread läuft:

private static ReentrantLock lock = new ReentrantLock();

void accessResource() {
    lock.lock();
    if( checkSomeCondition() ) {
        accessResource();
    }
    lock.unlock();
}

Da der Thread die Sperre besitzt, lässt er mehrere Aufrufe von lock() zu, so dass er die Sperre erneut eingeben kann. Dies kann mit einem Referenzzähler erreicht werden, so dass er die Sperre nicht erneut anfordern muss.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X