Re: einfaches Problem beim Synchronisieren



Ernst Baumann wrote:
Hallo allerseits,

Hallo.

[Problem mit Threads]

Kann mir jemand das erklären?

Ja, siehe unten.

------------ Beginn Demoprogramm ------------------
public class MainSynchronisieren1 {
public static void main(String[] args){
ThreadErzeuger einThreadErzeuger = new ThreadErzeuger();
ThreadVerbraucher einThreadVerbraucher = new ThreadVerbraucher(einThreadErzeuger); Thread t1 = new Thread (einThreadErzeuger);
Thread t2 = new Thread (einThreadVerbraucher); t1.start();
t2.start(); }
}

class ThreadErzeuger implements Runnable{
public int zahl;
public boolean verbraucherArbeitetGerade;
public Object MyLockObjekt = new Object();

public ThreadErzeuger(){
zahl = 0;
verbraucherArbeitetGerade = false;
}

public void erzeuge(){
synchronized(MyLockObjekt){

Hier holt sich t1 das Lock auf das MyLockObjekt.

while(verbraucherArbeitetGerade==true){
System.out.println("while-Schleife Erzeuger");
}
Und wenn t1 2x mal hintereinander an die Reihe kommt steckt er hier in einer endlos Schleife fest und gibt das Lock nicht mehr frei. t2 kommt also nicht mehr in den synchronized(MyLockObjekt){}-Block(unten markiert). Ergo kann dieser nichts machen.

// jetzt arbeitet der Verbraucher nicht mehr
zahl = zahl + 2;
System.out.println("Zahl im Erzeuger = "+zahl);
verbraucherArbeitetGerade=true;
}
System.out.println("E: Ende synchronisierung");
}

public void verbrauche(){

synchronized(MyLockObjekt){
^^^^^^^^^^^^^^^^^^^^^^^^^^
while(verbraucherArbeitetGerade==false){
System.out.println("while-Schleife Verbraucher");
}
// jetzt arbeitet der Erzeuger nicht mehr
zahl = zahl - 1;
System.out.println("Zahl im Verbraucher = "+zahl);
verbraucherArbeitetGerade=false;
}
}


[Rest vom Programm gesnipped]

Mein Vorschlag, wenn du über das verbraucherArbeitetGerade steuern willst, solltest du den synchronized-Block weglassen, oder du steuerst über dein MyLockObjekt und lässt die while-Schleifen weg.

Gruß David Grabandt
.