[Java] synchronized Threads Frage

08/05/2014 23:22 -Epitaph-#1
Heyho,

schaue mir gerade synchronized threads an und hab mir mal gedacht ich schreib nen kleines Programm, um zu sehen ob ichs verstanden habe. Und anscheinend versteh ichs noch nicht. Hier mal mein Programm und danach die Erklärung, was ich mit dem Programm bewerkstelligen wollte.

Code:
public class Main 
{
	public String s;
	public long i;
	
	Main(String s, long i)
	{
		this.s = s;
		this.i = i;
	}
	
	public synchronized void foo()
	{
		System.out.println("Start " + s + " Thread!");
		
		try 
		{
			Thread.sleep(i);
			wait();
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		
		System.out.println("End  " + s + " Thread!");
	}
	
	public static void main(String argv[])
	{
		new Thread()
		{
			public void run()
			{
				Main m = new Main("First", 3000);
				m.foo();
			}
		}.start();
		
		Main m = new Main("Second", 0);
		m.foo();
	}
}
2 threads: Unser Einstiegspunkt, also die main und der zweite thread, der in der main erstellt wird. Nun ührt der zweite thread eine synchronized Methode aus (die möglicherweise Daten enthalten könnte die nur von einem thread gleichzeitig bearbeitet werden sollten). Danach wird die Methode aus dem main thread aufgerufen. Was ich nun gedacht habe ist, dass beim aufruf der Methode von thread 2 die Methode locked, 3 Sekunden wartet und dann durch wait() den lock wieder frei gibt damit der main thread die Methode aufrufen kann... Jedoch wird die Methode von beiden threads sofort aufgerufen? Was habe ich falsch verstanden?^^

p.s.: Vorsicht Deadlock >:3
08/06/2014 10:56 Shadow992#2
Diese Art von synchronized, also das synchronized vor den Methodenrumpf, locked immer auf "this", also auf das aktuelle Objekt, das diese Methode aufruft. Ein lock kann man sich sehr intuitiv so vorstellen:

Sobald du vor eine Methode synchronized schreibst, wird in dieser Klasse ein neues Attribut angelegt, also eine neue Klassenvariable mit dem Namen "locked". Diese Variable kann jetzt die Werte true und flase annehmen. Wenn eine synchronized Methode ausgeführt wird, wird als aller erstes dieses locked auf true gesetzt. Alle anderen Threads warten dann bei diesem Methoden Aufruf desselben Objektes automatisch bis locked wieder auf false gesetzt wurde. Am Ende des Methoden Rumpfes wird locked automatisch wieder auf false gesetzt und dann wird dem anderem Thread gesagt "Schau mal ich bin fertig vielleich is locked jetzt auf false". Der andere Thread prüft es und ruft die Methode auf.

Was dein wait da oben soll verstehe ich nicht, ich kenne wait nur in Verbindung mit Monitoren also würde ich ganz spontan sagen mach es raus und lass die zwei Methoden auf ein und dasselbe Objekt aufrufen, dann sollte es so funktionieren wie du es dir vorgestellt hast. Solltest du dir sicher sein, dss wait an dieser Stelle passt, lass es drin, wie gesagt ich kenne es nr bei Monitoren und net bei synchronized aer wenn du dir sicher bist, dass es passt, lass es drin. ;)
08/06/2014 10:59 -Epitaph-#3
Ich bin so ein Idiot x3
Es wird ja das Objekt gelocked und da die Methoden bei zwei unterschiedlichen Objekten angewandt wird können beide Methoden gleichzeitig ausgeführt werden...

Thema kann gelöscht werden^^

Quote:
Originally Posted by Shadow992 View Post
Was dein wait da oben soll verstehe ich nicht, ich kenne wait nur in Verbindung mit Monitoren also würde ich ganz spontan sagen mach es raus und lass die zwei Methoden auf ein und dasselbe Objekt aufrufen, dann sollte es so funktionieren wie du es dir vorgestellt hast. Solltest du dir sicher sein, dss wait an dieser Stelle passt, lass es drin, wie gesagt ich kenne es nr bei Monitoren und net bei synchronized aer wenn du dir sicher bist, dass es passt, lass es drin. ;)
Oh garnet gesehen dass du noch vor mir geantwortet hast^^
Ich nehme an mit Monitor meinst einfach ne Methode die etwas beobachtet und dann darauf reagiert? wait() notify() und notifyAll() können ja laut dem Buch was ich lese nur in synchronized Methoden aufgerufen werden. Mit dem wait() wollte ich nur erreichen, dass die erste Methode vor dem zweiten System.out.println stopt und den lock an die zweite Methode übergibt. Nur so zum testen und verstehen halt ;) Normalerweise müsst da ja irgendwo nochn notify rein^^