# Frage zu synchronized



## M_Kay (8. April 2008)

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:

```
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


----------



## TheJadix (8. April 2008)

Hi,

Stimmt, dem ist eigentlich nichts mehr hinzuzufügen !

Gruß JAdix


----------



## zerix (9. April 2008)

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

MFG

Sascha


----------



## M_Kay (9. April 2008)

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?


----------



## zeja (9. April 2008)

Eine ganze interessante Seite zu dem Thema (und zu anderen Java-Themen): http://mindprod.com/jgloss/synchronized.html


----------



## M_Kay (9. April 2008)

Hehe, mein Englisch ist ein wenig eingerostet.
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


----------



## Kryptaesthesie (10. Juli 2009)

Guten Morgen 


M_Kay hat gesagt.:


> ...
> 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


----------



## Thomas Darimont (10. Juli 2009)

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:


```
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


----------



## zeja (10. Juli 2009)

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.


----------



## Kryptaesthesie (10. Juli 2009)

zeja hat gesagt.:


> 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.




```
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!


----------

