Thread Synchronisation

Status
Nicht offen für weitere Antworten.
A

Anton87

Gast
Hallo! Sitze seit Stunden an meinem Code und kriege es nicht hin :-(
Meine Klasse RWMonitor soll zulassen, dass verschiedene Threads auf dasselbe Objekt gleichzeitig Lesesperren ( mode='r' halten können. Aber es ist verboten das gleichzeig zu der Lesesperre die Schreibsperre mod ='w' gehalten wird. Die Threads müssen sozusagen zerstückelt das Programm ablaufen...
Der Fehler liegt denke ich in der lock() bzw unlock() Methode. Aber bloss wo....??
Die Trw Klasse erzeugt ein RWMonitor und 4 Threads. In der run() Mehtode soll mit zeitlicher Verzögerung jeweils die Schreibsperre bzw. Lesesperre gesetzt und freigegeben werden..
Was mache ich falsch?
Hat jemand einen Tipp? :roll:
Code:
public class RWMonitor extends Thread implements Runnable {
	
	static char mode;
	static Integer anzahlLeseSperre = 0;
	static boolean schreibSperre = false;

	

	public static synchronized void lock(Thread t, char mode){
		
		//Setzen der Lesesperre
		if ( mode=='r')
		{
		if(schreibSperre == false)  {anzahlLeseSperre++;}}
				
			else{
					
				while(schreibSperre != false ){
						
					try{Thread.sleep(10);}
					catch( InterruptedException e)
					{System.out.println("Ein Fehler ist aufgetreten" + e);}	
						}
						anzahlLeseSperre++;}
						
		//Setzen der Schreibsperre	
		if( mode =='w')
			
			if(schreibSperre == false && anzahlLeseSperre == 0) {schreibSperre = true;}
		
				else{
				
				while(schreibSperre!= false && anzahlLeseSperre > 0){
						
					try{Thread.sleep(10); }
					catch( InterruptedException e)
					{System.out.println("Es ist ein Fehler aufgetreten" + e);}
					}
					schreibSperre = true;}
		}

	
	public static synchronized void unlock(Thread t, char mode){
		//Entsperren der Lesesperre
		if ( mode=='r')
			
			if(anzahlLeseSperre!=0)
				
				{anzahlLeseSperre--; schreibSperre = false;}
		//Entsperren der Schreibsperre	

		if( mode =='w')
			
			if(schreibSperre == true) schreibSperre = false;
		}	
}

Code:
import java.lang.Math;

public class Trw extends Thread {
	
	//RWMonitor mon;
	
	public static void main (String [] arg){
		
	//RWMonitor mon = new RWMonitor();	
	
	Trw t1 = new Trw();
	Trw t2 = new Trw();
	Trw t3 = new Trw();
	Trw t4 = new Trw();
	
	t1.start();
	t2.start();
	t3.start();
	t4.start();
	
	}
	
	public void run(){
		
		//int counter=0;
		char [] mode  = {'r','w'};
		
		for (int z = 0;z<5;z++){

		// Punkt 1.
			try{Thread.sleep((long)(Math.random()*50+1));}
				catch(InterruptedException e){
					System.out.println("Ein Fehler"+ e);}
		// Punkt 2.
		RWMonitor.mode = mode [(int)(Math.random()*2)];
		
		System.out.println(currentThread().getName()+ 
				" steht vor Eintritt  " + "Mode = "+ RWMonitor.mode+" "+RWMonitor.anzahlLeseSperre+RWMonitor.schreibSperre);
		
		RWMonitor.lock(currentThread(), RWMonitor.mode);
		
		System.out.println(currentThread().getName()+ 
				" hat betreten        " + "Mode = "+ RWMonitor.mode+" "+ RWMonitor.anzahlLeseSperre+RWMonitor.schreibSperre);
		
		    try{Thread.sleep((long)(Math.random()*50+1));}
			catch(InterruptedException e){
				System.out.println("Ein Fehler"+ e);}
		
		RWMonitor.unlock(currentThread(), RWMonitor.mode);
		
		System.out.println(currentThread().getName()+ 
				
				" steht vor Verlassen " + "Mode = "+ RWMonitor.mode+" "+RWMonitor.anzahlLeseSperre+RWMonitor.schreibSperre);

		
	}
	}	
	}
 
S

SlaterB

Gast
da lag ja einiges im Argen, als aller erstes: Thread.sleep() gibt NICHT den synchronized-Block frei!

außerdem ist es schlecht, wenn sich nicht jeder Thread seinen mode merkt ;)
du gehts da mit dem Parameter mode einen richtigen Weg,
aber wenn als Parameter nur genau der statische Wert der Klasse übergeben wird, dann ist das erstens nutzlos (RWMonitor könnte genausogut selber die statische Variable anschauen),
viel schlimmer aber es ist falsch:
Thread 1 setzt den Mode auf r, geht rein, Thread 2 setzt den Mode auf w, geht rein,
nun will Thread 1 wieder raus, Mode ist w, wie soll Thread 1 wissen, dass er selber r ist?

--------

in lock noch zwei Fehler:
wenn der mode 'w' ist, dann wird das else des ersten ifs betreten, an deren Ende
> anzahlLeseSperre++;
steht

------

im richtigen w-Abschnitt steht
> while(schreibSperre!= false && anzahlLeseSperre > 0){

es wird also nur gewartet, wenn schreibsperre gesetzt ist UND auch noch Lesesperren da sind,
es muss aber auch dann gewartet werden, wenn nur eine dieser Bedingungen erfüllt ist

------

> import java.lang.Math;

aus java.lang muss man nixx importieren

-----
hier eine funktionierende Variante:

Code:
public class Trw extends Thread {

	static RWMonitor mon = new RWMonitor();

	public static void main(String[] arg) {

		// RWMonitor mon = new RWMonitor();

		Trw t1 = new Trw();
		Trw t2 = new Trw();
		Trw t3 = new Trw();
		Trw t4 = new Trw();

		t1.start();
		t2.start();
		t3.start();
		t4.start();

	}

	public void run() {

		// int counter=0;
		char[] mode = { 'r', 'w' };

		for (int z = 0; z < 5; z++) {

			// Punkt 1.
			try {
				Thread.sleep((long) (Math.random() * 50 + 1));
			} catch (InterruptedException e) {
				System.out.println("Ein Fehler" + e);
			}
			// Punkt 2.
			char m = mode[(int) (Math.random() * 2)];

			System.out.println(currentThread().getName() + " steht vor Eintritt   " + "Mode = " + m
					+ " " + mon.anzahlLeseSperre + mon.schreibSperre);

			mon.lock(m);

			System.out.println(currentThread().getName() + " hat betreten         " + "Mode = " + m
					+ " " + mon.anzahlLeseSperre + mon.schreibSperre);

			try {
				Thread.sleep((long) (Math.random() * 50 + 1));
			} catch (InterruptedException e) {
				System.out.println("Ein Fehler" + e);
			}

			System.out.println(currentThread().getName() + " steht vor  Verlassen " + "Mode = " + m
					+ " " + mon.anzahlLeseSperre + mon.schreibSperre);

			mon.unlock(m);

			System.out.println(currentThread().getName() + " steht nach Verlassen " + "Mode = " + m
					+ " " + mon.anzahlLeseSperre + mon.schreibSperre);

		}
	}
}

class RWMonitor {

	int anzahlLeseSperre = 0;
	boolean schreibSperre = false;

	public synchronized void lock(char mode) {
		// Setzen der Lesesperre
		if (mode == 'r') {
			while (schreibSperre) {
				try {
					wait();
				} catch (InterruptedException e) {
					System.out.println("Ein Fehler ist aufgetreten" + e);
				}
			}
			anzahlLeseSperre++;
		}

		// Setzen der Schreibsperre
		if (mode == 'w') {
			while (schreibSperre || anzahlLeseSperre > 0) {
				try {
					wait();
				} catch (InterruptedException e) {
					System.out.println("Es ist ein Fehler aufgetreten" + e);
				}
			}
			schreibSperre = true;
		}
	}

	public synchronized void unlock(char mode) {
		// Entsperren der Lesesperre
		if (mode == 'r') {
			anzahlLeseSperre--;
		}
		// Entsperren der Schreibsperre
		if (mode == 'w') {
			schreibSperre = false;
		}
		notify();
	}
}
 
A

Anton87

Gast
Vielen Dank!
Aber ich habe vergessen zu schreiben, dass unser Lehrer will, dass wir ohne die Funktionen notify, wait auskommen. Also nur mit synchronized und sleep(). Sonst wäre es ja zu einfach, sagt er.......
 
A

Anton87

Gast
wait() kann ich ja vielleicht durch sleep() ersetzen... Aber wie ersetze ich notify()??
 
S

SlaterB

Gast
wait kannst du eben nicht durch sleep ersetzen, da dadurch das synchronized nicht aufgehoben wird,
(solange kann niemand unlocken)

die Alternative wäre nun, dennoch wieder sleep zu benutzen, aber dafür den synchronized-Bereich zu verlassen,
entweder die ganze Operation lock(),
ein Rückgabewert true/ false gibt an, ob es geklappt hat oder ob gewartet werden muss + neuer Versuch,
oder innerhalb von lock mehrere synchronized(this) {}-Abschnitte und dazwischen mit sleep warten,

da jedes sleep selbstständig wieder aufhört ist dann auch kein notify() nötig
 

André Uhres

Top Contributor
Anton87 hat gesagt.:
unser Lehrer will, dass wir ohne die Funktionen notify, wait auskommen. Also nur mit synchronized und sleep(). Sonst wäre es ja zu einfach, sagt er.......
Er will euch beibringen, wie man falsch synchronisieren muss :lol:
 
A

Anton87

Gast
Hmm... Das hat der Lehrer uns natürlich nicht erzählt. Typisch...
Muss ich den ganzen Block für mode=r ein kappseln bzw. mode=w und zwischen den beiden GROßen warten mit sleep() oder einzelne teile innerhalb von großen IF-Abfragen einkapseln?
 
S

SlaterB

Gast
was du einkapseln musst ergit sich allein aus der Logik,
das Prüfen der Stati und deren Veränderung,

bisschen selber denken oder wenn nicht dann zumindest ausprobieren musst du schon,

unlock könnte übrigens völlig ohne synchronized auskommen
 
A

Anton87

Gast
Habe ich ja versucht... Ich weiss nicht genau, wo ich synchronized(Klasse.class) packen soll... Soll ich jede einzelne Abfrage abkapseln oder nur die GANZE Methode...??
Bei mir sieht dann so aus:
Code:
class RWMonitor1 { 

   int anzahlLeseSperre = 0; 
   boolean schreibSperre = false; 
   boolean upgradeSperre = false;


   public void lock(Thread t, char mode) { 
	   synchronized (RWMonitor1.class) {
		
	
      // Setzen der Lesesperre 
      if (mode == 'r') { 
         while (schreibSperre) { 
        	 try { 
                // wait(); 
        		Thread.sleep(10); 
        		   		 
              } catch (InterruptedException e) { 
                 System.out.println("Ein Fehler ist aufgetreten" + e); 
              } 
           } 
           anzahlLeseSperre++; 
        } 
	   }// Die Klammer von Synchronized
	   
	   synchronized (RWMonitor1.class) {

      // Setzen der Schreibsperre 
      if (mode == 'w') { 
         while (schreibSperre || anzahlLeseSperre > 0 || upgradeSperre) { 
            try { 
           //  wait(); 
              
             Thread.sleep(10); 
              
            } catch (InterruptedException e) { 
               System.out.println("Ein Fehler" + e); 
            } 
         } 
         schreibSperre = true; 
      } 
	}// Klammer von Synchronized
      synchronized (RWMonitor1.class) {
		
      // Setzen der UpgradeSperre
      if(mode=='u'){
    	  while(schreibSperre || upgradeSperre ){
    		  try {
    			//  wait();
    			  Thread.sleep(10);
    		  }catch (InterruptedException e) {
				System.out.println("Fehler"+e);
			  } 
    	  }   	  	  
    	  upgradeSperre = true;
      }
	 }
    } // ist die Klammer von Synchron

   public synchronized  void unlock(Thread t, char mode) { 
      // Entsperren der Lesesperre 
      if (mode == 'r') { 
         anzahlLeseSperre--; 
      } 
      // Entsperren der Schreibsperre 
      if (mode == 'w') { 
         schreibSperre = false; 
      } 
      // Entsperren der UpgradeSperre
      if( mode == 'u'){
    	  upgradeSperre = false;
      }
     // notify(); 
   } 
   
   // Für Aufgabe 4.2
   /*public synchronized void unlock(Thread t) {
	   
	      // Entsperren der Lesesperre 
	      if (anzahlLeseSperre!=0) { 
	         anzahlLeseSperre--; 
	      } 
	      // Entsperren der Schreibsperre 
	      if (schreibSperre == true) { 
	         schreibSperre = false; 
	      } 
	      notify(); 

}*/
}
 
A

Anton87

Gast
Und die geänderte TRW1 Klasse:
Code:
public class Trw1 extends Thread { 

   static RWMonitor1 mon = new RWMonitor1(); 

   public static void main(String[] arg) { 

	  
      Trw1 t1 = new Trw1(); 
      Trw1 t2 = new Trw1(); 
      Trw1 t3 = new Trw1(); 
      Trw1 t4 = new Trw1(); 

      t1.start(); 
      t2.start(); 
      t3.start(); 
      t4.start(); 

   } 

   public void run() { 

	  //char[] mode = { 'r', 'w'}; Nur für Punkt 4.1
      char[] mode = { 'r', 'w','u' }; 

      for (int z = 0; z < 5; z++) { 

         // Punkt 1. 
         try { 
            Thread.sleep((long) (Math.random() * 50 + 1)); 
         } catch (InterruptedException e) { 
            System.out.println("Ein Fehler" + e); 
         } 
         // Punkt 2. 3 
         //char m = mode[(int) (Math.random() * 2)]; 50% Wahrscheinlichkeit
         char m = mode[(int) (Math.random() * 3)]; // 1/3 Wahrscheinlichkeit
         
         System.out.println(currentThread().getName() + " steht vor Eintritt   " + "Mode = " + m 
               + " " + mon.anzahlLeseSperre + mon.schreibSperre); 

         mon.lock(currentThread(),m); 
         //mon.unlock(currentThread(), RWMonitor1.mode);
         
         //Punkt 4
         System.out.println(currentThread().getName() + " hat betreten         " + "Mode = " + m 
               + " " + mon.anzahlLeseSperre + mon.schreibSperre); 
         //Punkt 5
         try { 
            Thread.sleep((long) (Math.random() * 500 + 1)); 
         } catch (InterruptedException e) { 
            System.out.println("Ein Fehler" + e); 
         } 
         //Punkt 6
         System.out.println(currentThread().getName() + " steht vor  Verlassen " + "Mode = " + m 
               + " " + mon.anzahlLeseSperre + mon.schreibSperre); 
         //Punkt 7
         
         mon.unlock(currentThread(),m); 
         // mon.unlock(currentThread()); für Aufgabe 4.2
         
         System.out.println(currentThread().getName() + " steht nach Verlassen " + "Mode = " + m 
               + " " + mon.anzahlLeseSperre + mon.schreibSperre); 

      } 
   } 
}
 
A

Anton87

Gast
DANKE SCHÖN SlaterB!
Bin nun endlich selbst drauf gekommen...War eine schwere Geburt! VIELEN VIELEN DANK!!!!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
ralfb1105 Frage zu Thread Synchronisation mit wait() und notify() Java Basics - Anfänger-Themen 3
M Umgang mit Thread/ Synchronisation/ Deadlock-Vermeidung Java Basics - Anfänger-Themen 5
P Thread Synchronisation Java Basics - Anfänger-Themen 9
T Thread Synchronisation Java Basics - Anfänger-Themen 3
Dit_ Thread Synchronisation | Übung Java Basics - Anfänger-Themen 5
M thread synchronisation Java Basics - Anfänger-Themen 6
U Synchronisation, Thread Java Basics - Anfänger-Themen 4
D Vorschläge für Umstellung auf Thread-Nutzung erwünscht Java Basics - Anfänger-Themen 7
Z Sikuli Thread Fehler Java Basics - Anfänger-Themen 3
Leyla Thread isInterrupt Java Basics - Anfänger-Themen 18
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
F influxdb Upload in eigenem Thread Java Basics - Anfänger-Themen 2
frager2345 Thread - Methoden synchronized deklarieren Java Basics - Anfänger-Themen 10
berserkerdq2 Größter unterschied von extends thread und implements runnable? Java Basics - Anfänger-Themen 2
T Thread beenden aus zweiter Klasse Java Basics - Anfänger-Themen 4
A Thread - Synchronized Java Basics - Anfänger-Themen 10
A Thread Producer - Consumer Java Basics - Anfänger-Themen 1
A Thread-Semhapore Java Basics - Anfänger-Themen 0
A Thread Exchanger Java Basics - Anfänger-Themen 22
A Thread-Cyclicbarrier Java Basics - Anfänger-Themen 4
B In einem Thread Endlosschleife beenden Java Basics - Anfänger-Themen 19
A Thread-Verklemmung Java Basics - Anfänger-Themen 10
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
A Thread find number Java Basics - Anfänger-Themen 8
F Thread.sleep() Java Basics - Anfänger-Themen 5
F Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at main.main(main.java:11) Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 3
M Exception in thread "main" java.util.NoSuchElementException Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 8
B Compiler-Fehler Fehlermeldung Exception in thread, falsche Eingabewert Java Basics - Anfänger-Themen 2
M Thread-Zustände Java Basics - Anfänger-Themen 6
CptK For-Schleife in Thread nach jedem Durchlauf pausieren Java Basics - Anfänger-Themen 35
S Kriege Fehler "Exception in thread" beim Benutzen von SubStrings. Java Basics - Anfänger-Themen 2
B Endlosschleife Thread sauber beenden Java Basics - Anfänger-Themen 19
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 1
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 0
O Exception in thread "main" java.lang.ArithmeticException: / by zero Java Basics - Anfänger-Themen 4
C Thread und TimerTask, Verstädnisproblem Java Basics - Anfänger-Themen 10
amgadalghabra Sorting Thread Launcher Java Basics - Anfänger-Themen 3
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
A Thread Java Basics - Anfänger-Themen 4
A Thread Java Basics - Anfänger-Themen 1
A Thread Java Basics - Anfänger-Themen 0
R Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 5
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 1
B Thread / Prozess stoppen? Java Basics - Anfänger-Themen 22
I Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 Java Basics - Anfänger-Themen 3
B Threads Thread sleep() Method einfache Frage Java Basics - Anfänger-Themen 8
W Thread Aufgabe - Vorgehensweise Java Basics - Anfänger-Themen 8
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 0
J Threads PrograssBar update während thread Java Basics - Anfänger-Themen 13
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
S Thread.sleep mit JProgressBar Java Basics - Anfänger-Themen 1
R Exception in thread "main" java.lang.NullPointerException Java Basics - Anfänger-Themen 10
J JavaFX -> SocketIO -> Thread -> Update Label Java Basics - Anfänger-Themen 13
J Thread Handling Java Basics - Anfänger-Themen 9
A Problem mit Thread.sleep Java Basics - Anfänger-Themen 4
C Thread in Methode + raus aus der Schleife Java Basics - Anfänger-Themen 10
E Threads Thread in While-Schleife nur einmal starten Java Basics - Anfänger-Themen 2
F Daten von Thread an den aufrufenden zurückgeben Java Basics - Anfänger-Themen 22
C Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 Java Basics - Anfänger-Themen 3
B Thread Problem Java Basics - Anfänger-Themen 7
N KeyListener in Thread Java Basics - Anfänger-Themen 0
M Thread.sleep() Funktion Java Basics - Anfänger-Themen 1
W JLabel in Main aus Thread verändern. Java Basics - Anfänger-Themen 4
D Ausgeben welcher Thread gerade Arbeitet Java Basics - Anfänger-Themen 8
N Threads Thread-Fehler Java Basics - Anfänger-Themen 2
F Thread um Uhrzeit ausführen Java Basics - Anfänger-Themen 5
F Get/Post als eigener Thread mit Rückgabe Java Basics - Anfänger-Themen 5
J Exception in thread "main" Java Basics - Anfänger-Themen 1
F Thread der auf eine Queue wartet, sicher beenden Java Basics - Anfänger-Themen 4
B Animation mit Thread(s) Java Basics - Anfänger-Themen 23
I Thread.sleep (1000); Java Basics - Anfänger-Themen 1
M Threads Jede Klasse einem Thread zuweisen Java Basics - Anfänger-Themen 7
J Java Thread cancel() und wiederbeleben Java Basics - Anfänger-Themen 4
J BouncingBalls 1 Thread Java Basics - Anfänger-Themen 3
L Fehler: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 4
J Timer oder Thread programmieren ? Java Basics - Anfänger-Themen 10
fLooojava Laufender Thread | Boolean ändern Java Basics - Anfänger-Themen 9
T Thread Pool mit Work Stealing Java Basics - Anfänger-Themen 1
R Java Thread Java Basics - Anfänger-Themen 10
J Welche Methoden laufen im neuen thread ?? Java Basics - Anfänger-Themen 9
S Java memory fehler: Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa Java Basics - Anfänger-Themen 5
K Thread - Methoden in die run Methode Schreiben Java Basics - Anfänger-Themen 5
N Threads Exception in thread "main"... Feher bei dem Versuch ein Radius zu berechnen Java Basics - Anfänger-Themen 4
A Code läuft nicht, Fehlermeldung Exception in thread "main" java.lang.Error: Unresolved compilation " Java Basics - Anfänger-Themen 11
V Threads Exception in Thread behandeln Java Basics - Anfänger-Themen 3
S Methoden Multi-Thread und Methoden Objects. Java Basics - Anfänger-Themen 1
J Thread erstellen (BlueJ Projekt) Java Basics - Anfänger-Themen 3
P Exception in thread "main" java.lang.NoClassDefFoundError: Java Basics - Anfänger-Themen 1
F Threads Variable aus einem Thread in main Methode? Java Basics - Anfänger-Themen 9
K Exception in thread "main" Java Basics - Anfänger-Themen 7
L Thread-Frage Java Basics - Anfänger-Themen 2
E Was ist ein idle-thread? Java Basics - Anfänger-Themen 1
D Exception in thread "AWT-EventQueue-0" Java Basics - Anfänger-Themen 8
J Threads Prozess in Thread auslagern Java Basics - Anfänger-Themen 2
G Thread mehrmals starten und schliessen Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben