Sichtbarkeitssynchronisationen

synchronized, volatile, etc…

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Sichtbarkeitssynchronisationen
ich habe ein paar Fragen zu Sichtbarkeitssynchronisation, am Beispiel von einem Schreibtischlauf (Klausur 19.2.2013, A4)
hier der Link: https://www2.cs.fau.de/teaching/SS2014/PFP/organisation/oldexams/secure/13-02-19_klausur.pdf

  1. Wenn a nicht volatile wäre, könnte es passieren, dass der main-Thread Zeile 41 niemals verlässt? (main-Thread aktualisiert nie seinen Wert?)
  2. Wenn a nicht volatile wäre, könnte a trotz synchronized einen am Ende einen niedrigeren Wert als 4 haben? Oder stellt synchronized auch hier sicher, dass der nächste Thread, der a erhöhen will (Zeile 15/55) den aktualisierten Wert in seinem Cache hat?
  3. schafft es synchronized mit einem globalen lock Objekt generell, dass der nächste Thread, der den sync-Block betritt bei allen Variablen darin den Wert sieht, den der letzte Thread hineingeschrieben hat (unter der Voraussetzung, man kann sie nur darin ändern)? Oder gibt es da Ausnahmen?
  4. Wenn tB_4 schon vor Zeile 41 gestartet werden würde, könnte der Text aus Zeile 42 dann auch die vorletzte Ausgabe sein? (Wenn der main-Thread sehr langsam ist)

Es wäre wirklich sehr hilfreich, mir jemand die Fragen beantworten kann :slight_smile:


  1. ja (ausprobiert)
  2. nein, synchronized stellt sicher das die anderen threads die änderungen an a sehen - vorausgesetzt die Threads synchen am gleichen Objekt -was hier ja der fall sein sollte
  3. ja synchronized schafft das, vorausgesetzt die variablen kann man nirgendswo anders aufrufen
  4. Ja (ausprobiert)

falls was von meinen Aussagen nicht stimmt, bitte ich um Feedback

das meiste davon hab ich ausprobiert:

public class BarrierTest {

public static volatile int a= 0 , b= 0;

public static CyclicBarrier barrier = new CyclicBarrier(4);
public static CountDownLatch latch = new CountDownLatch(3);
public static Object lock = BarrierTest.class;

public static class MyThreadA extends Thread{
	
	public void run(){
		
		try{
			synchronized (lock){
				a++;
				System.out.println("a = "+ a);
				
			}
			barrier.await();
			if(b == 0){
				synchronized(lock){
					if(b == 0){
						b = 1;
					}
				}
				System.out.println("b = " + b);
			}
			latch.countDown();
		}catch (Exception e){}
	}
}

public static class MyThreadB extends Thread{
	
	public void run(){
		try{
			synchronized(BarrierTest.class){
				a++;
				System.out.println("a = "+ a);
			}
			barrier.await();
			if(b == 0){
				synchronized (lock) {
					if (b == 0){
						b = 2;
					}
				}
				System.out.println("b = "+b);
			}
			latch.countDown();	
		}	catch (Exception e){}
	}
}


public static void main (String[] args) throws Exception{
	Thread tA_1 = new MyThreadA();
	Thread tA_2 = new MyThreadA();
	Thread tB_3 = new MyThreadB();
	Thread tB_4 = new MyThreadB();
	tA_1.start();
	tA_2.start();
	tB_3.start();
	while(a < 3){}
	System.out.println("Trhead 1 , 2 , 3 started.");
	tB_4.start();
	latch.await();
	System.out.println("Thread 4 started.");
	tA_1.join();
	tA_2.join();
	tB_3.join();
	tB_4.join();
}

}


danke für die schnelle Hilfe :slight_smile: