Frage zu synchronized

M_Kay

Mitglied
Hi Leute,

ich habe mal eine Frage zu Synchronized.

In einem Objekt habe ich zwei Methoden. Es darf allerdings immer nur eine von beiden zum gleichen Zeitpunkt ausgeführt werden, da beide auf die selbe Ressourcen zugreifen.

Der Zugriff auf diese Methoden erfolgt via Threads, weshalb ich das ganze Synchronisieren muss, da ich ja nicht weiss, wann welche Methode aufgerufen wird.

Derzeit habe ich in beide Methoden (Methode a und Methode b) folgendes geschrieben:
Code:
synchronized (this) {
... code
}
Damit wird doch das komplette Objekt (bzw beide "sync-markierte" Methoden) vorübergehend für alle bis auf den aktiven Thread gesperrt, oder?
Also wenn Thread 1 gerade auf die Methode a zugreift, dann kann Thread 2 weder auf Methode a noch auf Methode b zugreifen, oder?
Habe ich das System soweit richtig verstanden? :)

Gruss
M_Kay
 
Du kannst dir natürlich auch überlegen locks zu nutzen. Die sind teilweise sogar schneller als synchronized.

MFG

Sascha
 
Erstmal vielen Dank für eure Antworten.

Gilt das oben genannte dann auch alles für Locks?
Mir ist halt wichtig, dass sobald eine von beiden Funktionen belegt ist, beide (!) für andere Threads gesperrt sind.

PS: Man kann doch direkt vor dem Methodennamen synchronized schreiben. Ist das das selbe, wie wenn ich den kompletten Inhalt der Funktion in den o.g. sync-Block setze?
 
Hehe, mein Englisch ist ein wenig eingerostet.:P
Aber so wie ich das verstanden habe, stimmt meine Vermutung, dass immer nur eine als synchronized markierte Methode zur selben Zeit ausgeführt werden kann. Alle anderen Methoden, die ebenfalls als synchronized markiert sind, müssen bei ihrem Aufruf warten.

Ist doch richtig so? :)

Und bei Locks ist das genauso?

Gruss
MKay
 
Guten Morgen :)
...
Aber so wie ich das verstanden habe, stimmt meine Vermutung, dass immer nur eine als synchronized markierte Methode zur selben Zeit ausgeführt werden kann. Alle anderen Methoden, die ebenfalls als synchronized markiert sind, müssen bei ihrem Aufruf warten.
...
Aber wenn ich zwei synchron markierte Methoden habe - bspw. a und b - können doch a und b zeitgleich ablaufen, oder? Nur zwei mal a ginge nicht.
Richtig?

Gruß
Gerrit
 
Hallo,

wenn du zwei Instanz Methoden einer Klasse mit synchronized deklariert hast kannst du diese Methoden nicht gleichzeitig an der selben Instanz von unterschiedlichen Threads aus ausführen. Als Monitor wird hier nämlich (this) die entsprechende Instanz verwendet. Bei Unterschiedlichen Instanzen ist das natürlich kein Problem.

synchronized bei static Methoden locked auf der Class-Instanz der Klasse in dem die static Methoden definiert sind.

Siehe:

Java:
package de.tutorials;

import java.util.concurrent.TimeUnit;

public class SynchronizedExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Bubu b = new Bubu();
		
		new Thread(){
			public void run() {
				for(int i = 0; i < 3;i++){
					b.a();
					
//					try {
//						TimeUnit.SECONDS.sleep(1);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
				}
			}
		}.start();
		
		new Thread(){
			public void run() {
				for(int i = 0; i < 3;i++){
					b.b();
					
//					try {
//						TimeUnit.SECONDS.sleep(1);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
				}
			}
		}.start();
		
	}

	static class Bubu {
		public synchronized void a() {
			System.out.println("calling a from " + Thread.currentThread());
			try {
				TimeUnit.SECONDS.sleep(3);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public synchronized void b() {
			System.out.println("calling b from " + Thread.currentThread());
			try {
				TimeUnit.SECONDS.sleep(3);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

Gruß Tom
 
Wie an den Beispielen im obigen Link zu sehen wird bei einer synchronized Instanzmethode ein Lock auf this ausgeführt. Damit müssen alle anderen synchronized Instanzmethoden der selben Klassen warten, da sie keinen Lock auf this ausführen können. Wenn du das nicht möchtest muss du selber synchronisieren.
 
Wie an den Beispielen im obigen Link zu sehen wird bei einer synchronized Instanzmethode ein Lock auf this ausgeführt. Damit müssen alle anderen synchronized Instanzmethoden der selben Klassen warten, da sie keinen Lock auf this ausführen können. Wenn du das nicht möchtest muss du selber synchronisieren.

Code:
public class SynchroTest {

    public SynchroTest() {
        // ...
    }
    
    public synchronized void runA() {
        // irgendwas ...
    }
    
    public synchronized void runB() {
        // irgendwas anderes ...
    }
    
    
    public static void main(String[] args) {
        SynchroTest st = new SynchroTest();
        
        synchronized(st) {
            st.runA();
        }
    }
}

in einem weiteren Synchronized-Block kann jetzt nicht zeitgleich runB() ausgeführt werden, wenn es sich auch um das Objekt st handelt, also das selbe Objekt, gleiche Instanz?

Also bei einer anderen Instanz des gleichen Objektes, also bspw. st2 kann dann aber wieder runA() und auch runB() zeitgleich ausgeführt werden, oder wie?

Ich dachte bis jetzt, das synchronized würde sich nur auf die eine Methode beziehen und nicht auf alle der gleichen Objekt-Instanz ...


Wieder was gelernt! :)
 

Neue Beiträge

Zurück