Threads: synchronized mach nicht was es soll?

Status
Nicht offen für weitere Antworten.

Shana

Mitglied
Hallo,

Ich habe 2 Thread-Klassen erstellt. Die run()-Methode enthält eine Schleife die von 1 bis 20 zählt und das Ergebnis ausgibt. Die Ausgabe ist dann so: Thread 1 und Thread2 werden "gemischt" ausgegeben, dh. es wird beispielsweise für Thread1 von 0 bis 15 gezählt, anschließen zählt Thread2 von 0 bis 18, dann Thread1 von 16 bis 20 und dann wieder Thread2 von 19 bis 20. Soweit so gut.

Synchronized sollte aber, falls ich das richtig verstanden habe, dafür sorgen, dass zuerst Thread1 von 1 bis 20 zählt und anschließen Thread2.

Mein Problem: Dies geschieht jedoch nicht.


Java-code:

Thread 1:
Code:
public class BspThread1 extends Thread{
	
	public  synchronized void Schleife1(){
			for(int i = 0; i<= 20; i++) {
				System.out.println("Thread1: " + i);
			} 
			
	}
		
	public void run(){
		 Schleife1();
	}

}

Thread 2:
Code:
public class BspThread2 extends Thread{
	
	public  synchronized void Schleife2(){
			for(int i = 0; i<= 20; i++) {
				System.out.println("Thread2: " + i);
			} 
			
	}
		
	public void run(){
		 Schleife2();
	}

}


Main-Methode:Startklasse
Code:
public class StartThreads {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		BspThread1 bspt1 = new BspThread1();
		BspThread2 bspt2 = new BspThread2();
		
		bspt1.start();
		bspt2.start();

	}

}

Ausgabe:
Code:
Thread1: 0
Thread1: 1
Thread1: 2
Thread1: 3
Thread1: 4
Thread1: 5
Thread1: 6
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Thread1: 11
Thread1: 12
Thread1: 13
Thread2: 0
Thread2: 1
Thread2: 2
Thread2: 3
Thread2: 4
Thread2: 5
Thread2: 6
Thread2: 7
Thread2: 8
Thread2: 9
Thread2: 10
Thread2: 11
Thread2: 12
Thread2: 13
Thread2: 14
Thread2: 15
Thread2: 16
Thread2: 17
Thread2: 18
Thread1: 14
Thread2: 19
Thread2: 20
Thread1: 15
Thread1: 16
Thread1: 17
Thread1: 18
Thread1: 19
Thread1: 20


Diese Ausgabe sollte eigentlich passen, wenn ich synchronized nicht verwende, aber nicht wenn ich dies tue oder?

Danke für eure Hilfe!
MfG Shana

PS: Ich habe die Suchfunktion verwendet und auch was zu dem Thema gefunden. Es sollte eigentlich funktionieren, jedoch hat mir das auch nicht geholfen, deswegen der Thread.
 
synchronized funktioniert nicht Programm-Global!

wenn BspThread1 auf sich selber synchronisiert, dann müssen alle warten, die auch auf das BspThread1-Objekt synchronisieren,
aber BspThread2 kocht sein eigenes Süppchen, die beiden haben nichts gemeinsam,

entweder einer der beiden Threads synchronisiert auf den anderen oder beide auf ein statisches Objekt oder so,

synchronized(object) {

}

es geht sogar

synchronized(StartThreads.class) {

}
 
Dieser Code
Code:
public class BspThreadX extends Thread{
   
   public  synchronized void schleifeX(){
         for(int i = 0; i<= 20; i++) {
            System.out.println("ThreadX: " + i);
         }
         
   }
      
   public void run(){
       SchleifeX();
   }
}

macht das gleiche wie

Code:
public class BspThreadX extends Thread{
   
   public  void schleifeX(){
         synchronized ( this) {
             for(int i = 0; i<= 20; i++) {
                System.out.println("ThreadX: " + i);
             }
         }
   }
      
   public void run(){
       schleifeX();
   }
}

Eine als synchronized deklarierte Instanz-Methode synchonisiert auf die jeweilige Instanz.

Um Dein Ziel zu erreichen, müssten beide Threads auf das gleiche Objekt synchronisieren.

Bsp:

Code:
class BspThreadBase extends Thread{

   static Object monitor = new Object();
}

class BspThread1 extends  BspThreadBase {
   
   public  void schleife1(){
         synchronized ( monitor) {
             for(int i = 0; i<= 20; i++) {
                System.out.println("Thread1: " + i);
             }
         }
   }
      
   public void run(){
       schleife1();
   }
}

class BspThread2 extends  BspThreadBase {
   
   public  void schleife2(){
         synchronized ( monitor) {
             for(int i = 0; i<= 20; i++) {
                System.out.println("Thread2: " + i);
             }
         }
   }
      
   public void run(){
       schleife2();
   }
}


//EDIT: da war Slater mal wieder schneller - schläfst du eigentlich nie??
 
Noch ein kleiner Tipp: seit Java 5 haben wir "java.util.concurrent.Executors.newSingleThreadExecutor"
was einen "Executor" erzeugt, der einen einzelnen Workerthread verwendet
um eine unbegrenzte Warteschlange abzuarbeiten.
Die Prozesse werden garantiert der Reihe nach durchgeführt
und jederzeit ist nicht mehr als ein Prozess aktiv:
Code:
import java.util.concurrent.*;
public class StartThreads {
    public static void main(final String[] args) {
        ExecutorService exe = Executors.newSingleThreadExecutor();
        exe.submit(new BspThread1());
        exe.submit(new BspThread2());
        exe.shutdown();//es werden keine weiteren Prozesse mehr angenommen
    }
}
class BspThread1 implements Runnable {
    public void run() {
        for (int i = 0; i <= 20; i++) {
            System.out.println("Thread1: " + i);
        }
    }
}
class BspThread2 implements Runnable {
    public void run() {
        for (int i = 0; i <= 20; i++) {
            System.out.println("Thread2: " + i);
        }
    }
}
 
hmm, reicht dann nicht ein einfacher eigener Thread, der die run-Methoden aufruft? 😉

gut, man spart sich 30 Zeilen selber zu programmieren, aber darauf musste man doch nicht bis 1.5 warten
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben