komplexe synchronized bedingungen

Stahlkocher

Mitglied
Hallo zusammen.

Ich habe mehrere Codeblöcke, nennen wir sie BlockA, BlockB und BlockC.
In alle dürfen so viele Threads rein wie wollen.

Nun hab ich einen Weiteren BlockX. Wenn hier ein Tread reinkommt, dann darf in keinem der anderen Blöcke ein Thread sein.

Ich könnte jetzt natürlich die drei Blöcke A, B und C mit drei verschiedenen Mutex (was ist eigentlich der plural von Mutex?) schützen. Und BlockX verwendet alle über ein dreifach verschafteltes synchronized. Aber dann kann in den Blöcken jeweils nur ein Thread, was eine zimliche Spaßbremse wäre...

Was ich bräuchte ist sowas wie ein "synchronized_read_only". Gibts ihrgendetwas in die Richtung? Wie könnte ich das umsetzten?

lg
Stahlkocher

Java:
public void functionA() {
  doSomething();
  synchronized(MutexA, read_only) {
    doSomething();
  }
  doSomething();
}

public void functionB() {
  doSomething();
  synchronized(MutexB, read_only) {
    doSomething();
  }
  doSomething();
}

public void functionC() {
  doSomething();
  synchronized(MutexC, read_only) {
    doSomething();
  }
  doSomething();
}

public void functionX() {
  doSomething();
  synchronized(MutexA) {
    synchronized(MutexB) {
      synchronized(MutexC) {
        doSomethingDirty();
      }
    }
  }
  doSomething();
}
 

tfa

Top Contributor
Vergiss synchronized ganz schnell wieder! Das Concurrency-Framework sollte dir das bieten, was du brauchst.
Schau dir ReentrantLock bzw. ReentrantReadWriteLock an.
 

Stahlkocher

Mitglied
Perfekt.

ReentrantReadWriteLock scheint genau das zu sein was ich brauche. Wusste garnicht, dass es in der java API ein synchronized-extended-framework gibt. Coole sache.

lg
Stahlkocher
 

tfa

Top Contributor
Ich hab spaßeshalber mal ein kleines Beispiel programmiert:

Java:
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ABCLock {

    static final Random rand = new Random();

    ReentrantReadWriteLock lockA = new ReentrantReadWriteLock();
    ReentrantReadWriteLock lockB = new ReentrantReadWriteLock();
    ReentrantReadWriteLock lockC = new ReentrantReadWriteLock();

    public void methodA() {
        try {
            this.lockA.readLock().lock();
            System.out.println("A " + Thread.currentThread().getName());
        }
        finally {
            this.lockA.readLock().unlock();
        }
    }

    public void methodB() {
        try {
            this.lockB.readLock().lock();
            System.out.println("B " + Thread.currentThread().getName());
        }
        finally {
            this.lockB.readLock().unlock();
        }
    }

    public void methodC() {
        try {
            this.lockC.readLock().lock();
            System.out.println("C " + Thread.currentThread().getName());
        }
        finally {
            this.lockC.readLock().unlock();
        }
    }

    public void methodX() {
        try {
            this.lockA.writeLock().lock();
            this.lockB.writeLock().lock();
            this.lockC.writeLock().lock();

            for (int i = 0; i < 10; i++) {
                System.out.println("X." + i);
                sleep(rand.nextInt(300));
            }
        }
        finally {
            this.lockA.writeLock().unlock();
            this.lockB.writeLock().unlock();
            this.lockC.writeLock().unlock();
        }
    }

    public void sleep(int t) {
        try {
            Thread.sleep(t);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public Runnable job() {
        return new Runnable() {
            public void run() {
                while (true) {
                    switch (rand.nextInt(3)) {
                        case 0: methodA(); break;
                        case 1: methodB(); break;
                        case 2: methodC(); break;
                    }
                    sleep(rand.nextInt(300));
                }
            }
        };
    }

    public void test() {
        for (int i = 0; i < 10; i++) {
            new Thread(job()).start();
        }

        Thread x = new Thread(new Runnable() {

            public void run() {
                while (true) {
                    methodX();
                    sleep(5000);
                }
            }
        });
        x.start();
    }

    public static void main(String[] args) {
        new ABCLock().test();
    }

}

10 Threads rufen wahllos die Methoden A, B und C auf. Bis Thread X daher kommt und die anderen zum Schweigen bringt.
 

Stahlkocher

Mitglied
Ich hab spaßeshalber mal ein kleines Beispiel programmiert
Was man Donnerstag nachmittags halt so macht :D

Danke für das beispiel.
Wenn ich das richtig verstanden hab könnte man das noch vereinfachen. Kann ich nicht alle drei Blöcke/Methoden mit nur einem ReentrantReadWriteLock'er schützen?

Java:
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;
 
public class ABCLock {
 
    static final Random rand = new Random();
 
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 
    public void methodA() {
        try {
            this.lock.readLock().lock();
            System.out.println("A " + Thread.currentThread().getName());
        }
        finally {
            this.lock.readLock().unlock();
        }
    }
 
    public void methodB() {
        try {
            this.lock.readLock().lock();
            System.out.println("B " + Thread.currentThread().getName());
        }
        finally {
            this.lock.readLock().unlock();
        }
    }
 
    public void methodC() {
        try {
            this.lock.readLock().lock();
            System.out.println("C " + Thread.currentThread().getName());
        }
        finally {
            this.lock.readLock().unlock();
        }
    }
 
    public void methodX() {
        try {
            this.lock.writeLock().lock();
 
            for (int i = 0; i < 10; i++) {
                System.out.println("X." + i);
                sleep(rand.nextInt(300));
            }
        }
        finally {
            this.lock.writeLock().unlock();
        }
    }
 
    public void sleep(int t) {
        try {
            Thread.sleep(t);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
    public Runnable job() {
        return new Runnable() {
            public void run() {
                while (true) {
                    switch (rand.nextInt(3)) {
                        case 0: methodA(); break;
                        case 1: methodB(); break;
                        case 2: methodC(); break;
                    }
                    sleep(rand.nextInt(300));
                }
            }
        };
    }
 
    public void test() {
        for (int i = 0; i < 10; i++) {
            new Thread(job()).start();
        }
 
        Thread x = new Thread(new Runnable() {
 
            public void run() {
                while (true) {
                    methodX();
                    sleep(5000);
                }
            }
        });
        x.start();
    }
 
    public static void main(String[] args) {
        new ABCLock().test();
    }
 
}

Der Consolen-output schaut danach aus als würds funktionieren :)

lg
Stahlkocher
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Java komplexe Map mit 2 values ? Allgemeine Java-Themen 8
U Klassen Komplexe Datenstruktur in Java Allgemeine Java-Themen 4
F Funktionsplotter komplexe Zahlen: geeignetes 3D-Koordinatensystem Allgemeine Java-Themen 16
P "Komplexe" Datenbankabfragen, welches ist der bessere Weg Allgemeine Java-Themen 4
K Command Line Argument Interpreter für komplexe Strukturen Allgemeine Java-Themen 9
J Synchronized Probleme Allgemeine Java-Themen 7
D ReentrantLock oder Synchronized ? Allgemeine Java-Themen 3
B Threads synchronized Allgemeine Java-Themen 3
OnDemand Threads und synchronized Allgemeine Java-Themen 9
N Best Practice Semi-Synchronized Zugriff Allgemeine Java-Themen 0
E Verständnisfrage zu synchronized-Blöcken Allgemeine Java-Themen 3
J yield() Aufruf in einer synchronized-Methode Allgemeine Java-Themen 13
A Frage zu Synchronized Allgemeine Java-Themen 5
R Synchronized - auf welchem Objekt Allgemeine Java-Themen 16
R synchronized methode rekursiv aufrufen Allgemeine Java-Themen 5
P synchronized Allgemeine Java-Themen 4
G synchronized Allgemeine Java-Themen 7
J Threads und synchronized Allgemeine Java-Themen 18
hdi synchronized & volatile Allgemeine Java-Themen 10
G zwei mal synchronized Allgemeine Java-Themen 5
J synchronized block mit this und wait() Allgemeine Java-Themen 5
M Verständnis "synchronized" Allgemeine Java-Themen 4
T Thread synchronized Allgemeine Java-Themen 5
Kr0e Synchronized Allgemeine Java-Themen 4
K synchronized und notify / notifyAll Allgemeine Java-Themen 8
G synchronized-Sclüsselwort: welche Reihenfolge zum Betreten? Allgemeine Java-Themen 6
R synchronized "gegen sich selbst" Allgemeine Java-Themen 5
R ConcurrentModificationException trotz synchronized? Allgemeine Java-Themen 12
R Thread-Problem, und synchronized bringt nix Allgemeine Java-Themen 4
J synchronized (bitte beantworten, urgent! danke) Allgemeine Java-Themen 11
H Ein synchronized Block ausreichend? Allgemeine Java-Themen 6
G synchronized Klasse? Allgemeine Java-Themen 6
G synchronized + threads Allgemeine Java-Themen 12
A deadlocks bei synchronized Allgemeine Java-Themen 3
K vector, synchronized und mehrere methoden Allgemeine Java-Themen 3
X Regex mit mehreren Bedingungen machen Allgemeine Java-Themen 5
looparda Bedingungen abstrahieren Allgemeine Java-Themen 11
J if-Bedingungen Allgemeine Java-Themen 4
Neumi5694 Vererbung Parameter muss 2 Bedingungen erfüllen Allgemeine Java-Themen 2
J Drei Bedingungen -> 9 Fällen, welcher Ansatz besser Allgemeine Java-Themen 4
T Überprüfen mathematischer Bedingungen Allgemeine Java-Themen 9
B Zwei Bedingungen für eine Anweisung Allgemeine Java-Themen 4
S Bedingungen-Array Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben