# Java Thread einfachste Grundlage



## 7123 (17. Jun 2008)

Hi,
sorry das ich hier so leichte Fragen stellen muss, aber ich habe erst vor 1 woche mit JAVA angefangen, hier meine Frage:
Wenn ich einen Thread mittels "implement Runnable" erstelle benötigt man ja keine main, jedoch gibt es auf dieser Seite, http://www.javacooperation.gmxhome.de/BallBewegungDeu.html
verschiedene Methoden wie z.b. init, start, usw (siehe seite). Also gleich vorweg, ich habe schon auf vielen Seiten versucht nachzulesen was die Methoden genau bewirken aber den richtigen "Durchblick" habe ich noch nicht. Also bitte ganz einfach erklären, wenn es geht  
Ich verstehe den Programmablauf nicht, was wird zuerst aufgerufen, die start() Methode und wo muss man die auf die run() mehtode beziehen?. Und warum wird die run() Methode immer wiederholt? Wenn die run() Methode beendet ist wird doch die paint() Methode ausgeführt, aber warum geht der Compiler dann wieder zur run() Methode zurück? Ich kenne bisher nur Programme mit main, ist bei Threads das anderes?

Ich hoffe ihr könnt mir weiter helfen, am besten wäre es wenn ihr mir das Prinzip der Thread noch mal ganz knapp erklären könnten, in den Tutorials ist das immer ziemlich kompliziert erklärt !!!

mfG


----------



## FArt (17. Jun 2008)

Das ist ein wenig zu viel...

http://www.galileocomputing.de/openbook/javainsel7/javainsel_10_001.htm#mj492cc74ea623bacbf44060ae96fdcf36

Kleiner Tipp: Es gibt Leute, die behaupten, Programmierung von Nebenläufigkeiten und deren korrekte Synchronisation sind die Königsdisziplin der Programmierung... von wegen Anfänger ... 
Deine Frage lässt vermuten, dass es für dich sinnvoll wäre erst die Grundlagen mal zu festigen...


----------



## Guest (17. Jun 2008)

Das Beispiel, dass du dir ausgesucht hast ist vielleicht etwas unglücklich gewählt, da es sich um ein Applet handelt.

Ich würde sagen du liest Dir das hier durch:
http://www.galileodesign.de/openbook/javainsel5/javainsel09_001.htm

Grundsätzlich läuft das mit Threads so:

1. Klasse, die in einem Thread laufen soll implementiert das interface Runnable (das die Klasse zwingt, die Methode run() zu implementieren). 

2. Erzeuge ein Threadobjekt und übergebe ein Objekt der Klasse.

Beispiel:

```
public class ThreadDemo {
	
	public static void main(String[] argv){
		
		RandomNumber randomnumber = new RandomNumber(); // erzeuge Objekt der Klasse
		Thread meinthread = new Thread(randomnumber);	// übergebe randomnumber Objekt einem Thread Objekt
		
		meinthread.start(); // starte thread
	}
	

}

// Programmcode der in einem eigenen Thread laufen soll
class RandomNumber implements Runnable{
	
	// hier ist der Startpunkt des Threads
	public void run(){
		for(int i=0;i<10;i++){
			System.out.println(Math.random());
		}
	}
}
```


----------



## 7123 (17. Jun 2008)

also bisher habe ich die Seite http://www.gailer-net.de/tutorials/java/java-toc.html#05
halbwegs "durchgearbeitet", bis auf Kapitel 7 und 10 die ich Momentan für nicht ganz so entscheident halte, das Problem ist das ich nicht weiß was noch alles Grundlagen sind, da es auf der Seite leider nicht mehr Kaptiel gibt. ich versuch mal meine Fragen von oben in einer Frage zu formulieren  

Bewirkt die run()  Anweisung, das der gesamte Programmcode der Klasse noch einmal durchgeführt wird, bis die Bedingung der run() Methode falsch ist?


----------



## FArt (17. Jun 2008)

Die run() Methode wird (nachdem man auf der Threadinstanz start() aufgerufen hat) einmal aufgerufen. Wenn sie durchlaufen ist, ist der Thread beendet.


----------



## 7123 (17. Jun 2008)

aber während die run() Methode ausgeführt wird parellel noch der sich der run() Methode anschließende Programmcode, z.b. eine paint() Methode, die ein Rechteck zeichnet , das ist doch der Sinn der run() Methode, oder bin ich da völlig auf dem falschen weg?


----------



## Gast (17. Jun 2008)

Welche Bedingung der run() Methode?

Nein, du musst dir das so vorstellen: Eine Klasse, die das Interface Runnable implementiert, also eine run() Methode hat, überhaupt erst die Möglichkeit hat, als Thread ausgeführt zu werden. run() ist einfach der Startpunkt des Threads. run() wird aber nie "per Hand" aufgerufen, sondern dient dem Thread als eine Art Erkennungsmarke wo er mit der Ausführung beginnen muss.

Du übergibst, wie in meinem Beispiel oben, einem Thread Objekt deine Klasse (die das Interface runnable implementiert). 

Über thread.start() wird deine Programmcode, der in der run() Methode steckt, nebenläufig, also als eigener Thread ausgeführt.


----------



## Guest (17. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> aber während die run() Methode ausgeführt wird parellel noch der sich der run() Methode anschließende Programmcode, z.b. das Zeichnen eines Rechtecks ausgeführt, das ist doch der Sinn der run Methode, oder?



run() dient nur als Einstiegspunkt in den Thread. Was du innerhalb von run() aufrufst wird auch in diesem Thread ausgeführt:

```
public class ThreadDemo {
	
	public static void main(String[] argv){
		
		RandomNumber randomnumber = new RandomNumber(); // erzeuge Objekt der Klasse
		Thread meinthread = new Thread(randomnumber);	// übergebe randomnumber Objekt einem Thread Objekt
		
		meinthread.start(); // starte thread
	}
	

}

// Programmcode der in einem eigenen Thread laufen soll
class RandomNumber implements Runnable{
	
	// hier ist der Startpunkt des Threads
	public void run(){
		for(int i=0;i<10;i++){
			System.out.println(Math.random());
		}
		sagwas();
		paintSonstwas()... usw.
	}
	
	private void sagwas(){
		System.out.println("Hallo Welt");
	}
}
```


----------



## 7123 (17. Jun 2008)

Hm, ich möchte doch noch mal auf den Code von der oben genannten Seite eingehen:


```
public void run ()
{ 

Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (true)
{ 
	x_pos ++;
	repaint();
try
{ 
Thread.sleep (50);
}
catch (InterruptedException ex)
{ 
}

Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
} 
} 

public void paint (Graphics g)
{ 

g.setColor (Color.red);

g.fillOval (x_pos - radius, y_pos - radius, 2 * radius, 2 * radius);
}
```
hier mal ein Auschnitt aus dem Code, in dem Beispiel wird ja ein roter Ball vom linken Bildschirmrand nach rechts bewegt. Ich verstehe nur eins nicht: Zuerst wird doch die run() Methode ausgeführt x_pos wird erhöht und der Sreen neu gezeichnet, soweit so gut, aber der eigentliche "rote Ball" wird doch erst in der paint Methode erstellt und wenn die zu ende ist müsste das Programm doch auch zu ende sein. Jedoch scheint das Programm dann wieder in die run() Methode zu springen diese auszuführen und dann wieder in die paint() usw. Ich kann nicht nachvollziehen warum die beiden Methoden immer wieder ausgeführt werden, ich hoffe ich konnte mein Problem jetzt etwas deutlicher machen


----------



## Guest (17. Jun 2008)

Also,

beim Starten des Applets wird ein kleiner roter Kreis auf dem Panel ganz links gezeichnet.
Dann wird der Thread gestartet mit th.start(); Das heisst es geht weiter in der run() Methode.
Un dort ist eine *Endlosschleife (while(true):*Das heisst, auch wenn der rote Kreis schon längst rechts verschwunden ist, befindet sich das Programm immer noch in dieser Schleife.

Durch x_pos++; wird die globale Variabe x_pos um eins erhöht. Wird anschließend repaint() aufgerufen wird die gesamte Oberfläche neu gezeichnet, das bedeutet, dass auch paint aufgerufen wird und den Kreis neu zeichnet mit neuer x_pos Koordinate.

Danach schläft der Thread 50 ms, so dass das man die Bewegung auch noch erkennen kann.


----------



## 7123 (17. Jun 2008)

Ach repaint() ruft ja automatisch die paint() Methode auf, deshalb wird das Bild jedesmal neu gezeichnet, sry für die Frage von oben, jetzt wird mir so einiges klar... . Was ich aber immer noch nicht verstehe ist das Prinzip der run() Methode, ich hab mal in einem Tutorial gelesen, das durch die run() Methode mehrer Programmcodes gleichzeitig ausgeführt werden (Multithreading), aber warum ist das in dem Beispiel nicht so, wenn man z.b. noch einen Programmcode z.b. das Zeichen eines Rechteckes in einer anderen Klasse anhängt, würde dieser dann parallel zur Bewegung des Kreises ausgeführt?

Anm.: "@Gast": Wieso wird der Kreis zuerst gezeichnet, die Paint() Methode wird doch erst in der Run() Methode aufgerufen, also müsste der Kreis beim Starten des Threades noch gar nicht existieren, erst wenn der Thread repaint() aufruft, oder?


----------



## Guest (17. Jun 2008)

paint() ist eine Methode des Applets.
Die Klasse Ballbewegung1 erbt von der Klasse Applet:

```
Ballbewegung1 extends Applet
```
Dann wird die Methode paint() überschrieben also mit eigenem Programmcode gefüllt.

repaint() bewirkt, dass das Applet neu gezeichnet wird. Da ein Neuzeichnen auch den Aufruf von paint() beinhaltet, wird paint() ausgeführt und dein Kreis um eins nach rechts versetzt gezeichnet.

Ich sagte ja, befasse dich nicht gleich mit einem Applet ;-)


----------



## Leroy42 (17. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> Ach repaint() ruft ja automatisch die paint() Methode auf, deshalb wird das Bild jedesmal neu gezeichnet



Nicht ganz! repaint() veranlaßt nur den EDT die paint-Methode aufzurufen, sobald
er wieder _dran ist_.



			
				Gast 7123 hat gesagt.:
			
		

> Anm.: "@Gast": Wieso wird der Kreis zuerst gezeichnet, die Paint() Methode wird doch erst in der Run() Methode aufgerufen, also müsste der Kreis beim Starten des Threades noch gar nicht existieren, erst wenn der Thread repaint() aufruft, oder?



Nein! Erst in der run-Methode wird der EDT aufgefordert, paint _erneut_ auszuführen.

Das paint() wird zusätzlich immer dann aufgerufen, wenn der EDT meint es aufrufen zu müssen.

Also ganz _zu Anfang_ und automatisch immer dann, wenn der Zeichenbereich erneut
in den Vordergrund kommt (zum Beispiel wenn man ein anderes Fenster _darüberzieht_ oder
das Zeichenfenster zwischenzeitlich minimiert wurde.


----------



## 7123 (17. Jun 2008)

Danke erstmal für eure Hilfe, jetzt hab ich zumindest verstanden wie das Programm abläuft, aber eine Frage hab ich doch noch^^ Warum schreibt man den ganzen Ablauf (roter Ball bewegt sich von links nach rechts) nicht in eine einzige main mit einer while schleife und schreibt in die Schleife den ganzen Code hinein?

@Leroy: 1.Was ist EDT?^^
             2. Bedeutet das das bei einem Applet immer zuerst die paint( ) Methode aufgerufen wird, bevor eine andere Methode wie der Aufruf von run( ) bewerkstelligt wird?


----------



## Gast (17. Jun 2008)

EDT = Event Dispatcher Thread = Der Thread in dem die GUI ausgeführt wird.

Aber warum der Kreis, wenn er in der while Schleife erzeugt wird, flackert das müssten dann die Profis beantworten:

```
package various;
import java.applet.*;
import java.awt.*;

public class Ballbewegung1 extends Applet implements Runnable
{
	// Initialisierung der Variablen
	int x_pos = 10;		// x - Position des Balles
	int y_pos = 100;	// y - Position des Balles
	int radius = 20;	// Radius des Balles

	public void init()
	{
		setBackground (Color.blue);
	}

	public void start ()
	{
		// Schaffen eines neuen Threads, in dem das Spiel läuft
		Thread th = new Thread (this);
		// Starten des Threads
		th.start ();
	}

	public void stop()
	{

	}

	public void destroy()
	{

	}

	public void run ()
	{
		// Erniedrigen der ThreadPriority um zeichnen zu erleichtern
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

		// Solange true ist läuft der Thread weiter
		
		while (true)
		{

			// Verändern der x- Koordinate
			x_pos ++;

			// Neuzeichnen des Applets
			repaint();

			Graphics g = this.getGraphics();
			g.setColor  (Color.red);
			g.fillOval (x_pos - radius, y_pos - radius, 2 * radius, 2 * radius);
			
			try
			{
				// Stoppen des Threads für in Klammern angegebene Millisekunden
				Thread.sleep (20);
			}
			catch (InterruptedException ex)
			{
				// do nothing
			}

			// Zurücksetzen der ThreadPriority auf Maximalwert
			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		}
	}
}
```


----------



## Leroy42 (17. Jun 2008)

Gast hat gesagt.:
			
		

> Aber warum der Kreis, wenn er in der while Schleife erzeugt wird, flackert das müssten dann die Profis beantworten:



Einfach weil dein repaint-Aufruf in der while-Schleife zuerst immer den Bildschirm löscht.

Stichwort: Kein DoubleBuffering.

Außerdem:


```
Graphics g = this.getGraphics();
// mit g herumhantieren
```

Ganz ganz böse!  :noe:


----------



## 7123 (17. Jun 2008)

hab noch mal einige Fragen zu Befehlen, was macht eigentlich (this), (try) und eben dieses (Graphics g)? Ich hab jetzt mal versucht einen code aus einem Tutorial auszuführen, aber da steht immer das die Main Class nicht gefunden wird, hier mal der Code:


```
public class b
 extends Thread
 {
   int cnt = 0;
 
   public void run()
   {
     while (true) {
       if (isInterrupted()) {
         break;
      }
      printLine(++cnt);
    }
   }
 
   private void printLine(int cnt)
   {
     //Zeile ausgeben
     System.out.print(cnt + ": ");
     for (int i = 0; i < 30; ++i) {
     System.out.print(i == cnt % 30 ? "* " : ". ");
     }
     System.out.println();
     //100 ms. warten
     try {
       Thread.sleep(100);
     } catch (InterruptedException e) {
       interrupt();
    }
   }
 
   public static void main(String[] args)
   {
     b th = new b();
     {
       //Thread starten
       th.start();
       //2 Sekunden warten
       try {
         Thread.sleep(2000);
       } catch (InterruptedException e) {
       }
       //Thread unterbrechen
       th.interrupt();
     }
   }
 }
```

hab auch mal das Programm von "Gast" eine Seite weiter vorne getestet, da kommt der selbe Fehler: Couldnt find main class


----------



## Baunty (18. Jun 2008)

Ich hab keine Ahnung von Threads aber ich mein ich hät eben noch gelesen das man Runnable implementieren muss...
Und wenn das nen Applet ist musst du es auch als applet starten & nich als java app.. 
korrigiert mich wenn ich falsch liege ;-)


----------



## SlaterB (18. Jun 2008)

extends Thread reicht alternativ zu Runnable,

Klassen sollte man groß schreiben,
Klassen müssen genauso heißen wie die sie enthaltenen Dateien

wenn man es nicht schafft, ein Programm mit einer main-Operation zu starten, was ja nun ein ganz zentraler Baustein zum Ablauf eines Programmes ist,
dann sollte man sich erstmal an einem Hello World-Programm vom ersten Kapitel eines Lehrbuches versuchen,

auch wenn man das schon kennt, nur um sich wieder zu überzeugen, wie es geht 
und dann das funktionierende mti dem nicht funktionierenden Programm Schritt für Schritt vergleichen:
Klasse umbenenen, notfalls jede unterschiedliche Codezeile einzeln einfügen


----------



## 7123 (18. Jun 2008)

"Klassen sollte man große schreiben"!!! Danke, das wusste ich nicht jetzt geht es, gibt es eigentlich einen unterschied zwischen extend thread und implement runnable?


----------



## Leroy42 (18. Jun 2008)

Ja, den gibt es.

Genaueres findest du hier

Sorry, aber ein bischen lesen muß man schon selbst.  :meld:


----------



## 7123 (18. Jun 2008)

also implements runnable verwendet man um applets threatfähig zu machen und exten d Thread bei anderen, ist das so richtig?


----------



## FArt (18. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> also implements runnable verwendet man um applets threatfähig zu machen und exten d Thread bei anderen, ist das so richtig?


Schwachsinn.

Du bist einer von den Lernresistenten, oder?

Bitte mein erstes Posting in diesem Thread (nicht Runnable...ROFL) befolgen, davor sinnvollerweise noch Lerory42s Anweisung befolgen, sonst wird das nichts.


----------



## 7123 (19. Jun 2008)

Hab auf eueren rat noch einmal von vorne angefangen und mal 2 Klassen erstellt, aber diese 2 Klassen können ja nicht beide wie das Projekt heißen, die Klassen heißen Klasse1 und Klasse2, also muss ich doch Klasse 1 in Klasse1.java und Klasse 2 in Klasse 2.java speichern, aber wie kann ich nun in Klasse 1 die Klasse 2 aufrufen, die ich brauche um ein Objekt zu erzeugen (da Klasse 2 ja jetzt in einer anderen Datei ist)?


----------



## FArt (19. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> Hab auf eueren rat noch einmal von vorne angefangen und mal 2 Klassen erstellt, aber diese 2 Klassen können ja nicht beide wie das Projekt heißen, die Klassen heißen Klasse1 und Klasse2, also muss ich doch Klasse 1 in Klasse1.java und Klasse 2 in Klasse 2.java speichern, aber wie kann ich nun in Klasse 1 die Klasse 2 aufrufen, die ich brauche um ein Objekt zu erzeugen (da Klasse 2 ja jetzt in einer anderen Datei ist)?



Ne, du hast nicht ganz von vorne angefangen. Ganz von vorne ist die erste Seite von "Java ist auch eine Insel". So ziemlich am Anfang wird dann auch die Lösung zu deiner letzten Frage gebeben... noch ganz ohne Threads.


----------



## 7123 (19. Jun 2008)

Ich meine mit von vorne angefangen nicht das ich dieses E-Book lese, ich verwende andere Quellen weil mir den Art auf der das Buch geschrieben ist zu kompliziert ist, warum könnt ihr  mir nicht einfach mal sagen wo es steht, ich kann doch nicht alle seiten durchlesen außerdem ist "so ziemlich am anfang" relativ (sag doch wenigstens mal das kapitel oder wenn du weißt wie es geht das prinzip)


----------



## Guest (19. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> Hab auf eueren rat noch einmal von vorne angefangen und mal 2 Klassen erstellt, aber diese 2 Klassen können ja nicht beide wie das Projekt heißen, die Klassen heißen Klasse1 und Klasse2, also muss ich doch Klasse 1 in Klasse1.java und Klasse 2 in Klasse 2.java speichern, aber wie kann ich nun in Klasse 1 die Klasse 2 aufrufen, die ich brauche um ein Objekt zu erzeugen (da Klasse 2 ja jetzt in einer anderen Datei ist)?



hä?

Angenommen du hast ein package demo. Darin enthalten sind Klasse1 und Klasse2. Dann kannst du doch von Klasse1 auf Klasse2 zugreifen:

```
package demo;

public class Klasse1 {
	public static void main(String[] argv){
		Klasse2 objektvonklasse2 = new Klasse2();
		objektvonklasse2.sagHallo();
	}
}
```


```
package demo;

public class Klasse2 {
	public void sagHallo(){
		System.out.println("Hallo Welt");
	}
}
```


----------



## 7123 (19. Jun 2008)

und wie bekomme ich Klasse  1  und Klasse  2 in das package demo :?:


----------



## Leroy42 (19. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> und wie bekomme ich Klasse  1  und Klasse  2 in das package demo :?:



Genauso, wie gast es beschrieben hat.

Durch


```
package demo;

public class Klasse1 {
...
}
```

ist Klasse1 bereits in dem package _demo_!


----------



## 7123 (19. Jun 2008)

ok, das ist ja einfach  müssen die beiden Dateien .class dann im selben ordner gespeichert werden oder ist das egal, bzw. muss man die in einen speziellen Ordner speichern?


----------



## Gast (19. Jun 2008)

Ein package wird physisch als Ordner realisiert.


----------



## 7123 (20. Jun 2008)

sry, ich habe noch eine Frage^^ Warum funktioniert der folgende befehl? 
	
	
	
	





```
public class Hallo {Hallo eins;}
```

Die Konstruktor ist ja default, aber warum kann man jetzt einfach in einer Klassendefinition Objekt des Typs Hallo erzeugen, obwohl nicht festgelegt ist, was ein Objekt Hallo eigentlich ist (da Hallo ja keine Daten enthält bzw. durch einen Kostruktor zugewiesen bekommt)


----------



## SlaterB (20. Jun 2008)

klar ist das Objekt festgelegt,
jeder compilierbare Code ist ein 'festgelegter' Code,

man kann Hallo-Objekte erzeugen,
dann ist eins darin leer oder kann von außen etwas zugewiesen bekommen,
diese Klasse kann also sogar echte Funktionalität übernehmen, z.B. zur Zählung:
wenn man die Zahl fünf darstellen will, verknüpft man einfach 5 Hallo-Objekte 

es gibt übrigens auch Interface udn abstrakte Klassen, zu denen man keine Objekte erzeugen kann,
dennoch ist die Deklaration entsprechender Variablen erlaubt,
weil man Objekte von SubKlassen darin speichern kann

------


zum Hallo-Beispiel: man sollte aber darauf achten, nicht in einem Konstruktor ein weiteres Hallo-Objekt für die eins Variable zu erstellen -> Endlosschleife


----------



## 7123 (20. Jun 2008)

Achso, danke für die Erklärung, aber da du gerade Schnittstellen angesprochen hast, hab ich da auch gleich noch einmal eine Frag dazu^^: Was ist eigentlich der Vorteil einer Schnittstelle gegenüber einer Subklasse, klar man kann in der Schnittstelle feste Variblen definieren, aber das könnte man doch auch in der Subklasse und die Methoden die man in der Schnittstelle festlegt kann man doch auch einfach ohne die Schnittstelle in die Subklasse schreiben, man verpflichtet sich ja noch durch die Schnittstelle mehrere Methoden auszuführen, da bringt es auch nichts wenn man mehrer Schnittstellen implementiert, da man eh in der Subklasse noch einmal alle Methoden neu schreiben darf, also was ist der Vorteil einer Schnittstelle, hoffe jemand kann mir das noch einmal so gut erklären wie SlaterB


----------



## FArt (20. Jun 2008)

*Tüte Chips und Bier hol*

:bae: 

Wird noch ein interessanter Thread, mal sehen wie lange das noch so geht... ich tippe auf 5 Seiten. Wer bietet mehr?


----------



## diggaa1984 (20. Jun 2008)

mit ner schnittstelle versteckst du die eigenltiche Implementierung dieser vor dem Nutzer der Schnittstelle.
Somit kannst die selben Methoden auf versch. Realisierungen dieser Schnittstelle aufrufen, und somit kannst relativ einfach Klassen austauschen ohne grossartig im Code rumzuändern:

```
List<String> list1;

list1 = new ArrayList<String>(); //oder zB
list1 = new LinkedList<String>();
```

ohne nun zig Stellen im Code zu ändern wo du mit list1 arbeitest kannst einfach die jeweilige implementierende Klasse des Interfaces wechseln.



			
				FArt hat gesagt.:
			
		

> ich tippe auf 5 Seiten. Wer bietet mehr?



meeehr  .. aber is schon richtig, Forensuche nutzen, findet man genug, und wenn das nich hilft wenigstens n neuen thread erstellen. Obwohl ersteres fruchten sollte


----------



## 7123 (20. Jun 2008)

hoffe nicht das es mehr als 5 seiten werden  ; obwohl das Niveau der Fragen bisher nicht besser geworden ist, ich weiß  , wie habt ihr das ganze Wissen eigentlich gelernt (nur über das Java Insel Buch?)

Also das mit der Schnittstelle und dem Vorteil hab ich noch nicht ganz verstanden, ich mache mal ein Beispiel:
z.b. eine Schnittstelle Liste mit der Methode Ausgabe:


```
public interface Liste
{public void Ausgabe};}

public class Beispiel implements Liste
{public void Ausgabe ()
{System.out.println("Ich verstehe das (noch) nicht")}
}
```

Hoffe der Code stimmt   Also, die Klasse Beispiel würde ja auch ohne das interface funktionieren, aber wie meinst du das mit der implementierungändern, ich könnte doch z.b. noch eine zweite Klasse erstellen, welche auch die gleiche Methode hat, warum spare ich da Code ein?


----------



## diggaa1984 (20. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> wie habt ihr das ganze Wissen eigentlich gelernt (nur über das Java Insel Buch?)


lesen, [fragen,] üben, verstehen 

Bsp:

```
public interface Sortierer {
    public void sortiere(int[] liste);
}

*******************************

public class BubbleSort implements Sortierer {
    public void sortiere (int[] liste) {
        //BubbleSort-algorithmus
    }
}


public class Quicksort implements Sortierer {
    public void sortiere (int[] liste) {
        //Quicksort-algorithmus

    }
}

public class Mergesort implements Sortierer {
    public void sortiere (int[] liste) {
        //Mergesort-algorithmus
    }
}
******************************

public class Test {

    Sortierer sorter;
    int[] testdaten = {2,1,4,3,6,5,8,6,9,7};
 
    public Test() {
        sorter = new Bubblesort();
        sorter.sortiere(testdaten)
    }
} //nicht getestet
```

so wennu nun lieber Quicksort statt Bubblesort wöhlen willst, dann brauchst du nur im Kontruktor von Test statt Bubblesort Quicksort schreiben. uns alles andere wäre davon unberührt (sprich in dem fall der aufruf von "sortiere").

irgendwie deutlicher?


EDIT: les grad noch was anderes in deiner Frage 
machen wir ma sowas:


```
public class MainClass {
    public static void main(String[] args) {
        Sortierer s = new Bubblesort();
        Test t = new Test(s);
    }
}

//edit Testclass

public class Test {
    private Sortierer sorter;
    int[] testdaten = {2,1,5,3,7,4,8,5,3,9};

    public Test(Sortierer s) {
        sorter = s;  
        sorter.sortiere(testdaten);
    }
}
```

somit kannst du mit nur einer änderung in der mainclass die genutzte implementierung ändern, ohne zusätzlich den Parameter im Konstruktor der Testklasse anzupassen an den neuen Typ.

Glaube das wars was du wolltest.


----------



## FArt (20. Jun 2008)

Das beste Beispiel ist das Collection Framework:

List, Map als Interface und die verschiedenen Implementierungen.

Ich muss ja schauen, dass der Thrad wächst... darf jetzt jeder, der eine Antwort schreibt die nächste Frage stellen oder wie sind die Regeln?


----------



## 7123 (20. Jun 2008)

ich glaube langsam verstehe ich das, aber noch einmal eine Frage zum Verständnis, wenn ich jetzt deinen Code ohne das Interface schreibe...


```
public class BubbleSort  { 
    public void sortiere (int[] liste) { 
        //BubbleSort-algorithmus 
} 


public class Quicksort  { 
    public void sortiere (int[] liste) { 
        //Quicksort-algorithmus 

} 

public class Mergesort  { 
    public void sortiere (int[] liste) { 
        //Mergesort-algorithmus 
} 

****************************** 

public class Test { 

    BubbleSort sorter; //Änderung 1
    int[] testdaten = {2,1,4,3,6,5,8,6,9,7}; 

    public Test() { 
        sorter = new Bubblesort(); //Änderung 2
        sorter.sortiere(testdaten) 
    } 
}
```

... müsste ich jedesmal 2 Zeilen ändern um die Methode einer anderen Klasse anzuwenden (siehe Änderung im Code), also hätte mir dieser Code nur den Vorteil gebracht das ich bei einer Änderung 1 Zeile weniger ändern müsste, richtig? (könnte bei Änderung 1 auch "Object sorter;" schreiben bei diesem Beispiel?)


----------



## diggaa1984 (20. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> könnte bei Änderung 1 auch "Object sorter;" schreiben bei diesem Beispiel?



Können: JA ... Sollte: NEIN  
du müsstest dein Object bei jeder Benutzung von "sorter" in den jeweiligen Sort casten.

Der eigentliche Nutzen des Interfaces wird im bsp ersichtlich was ich oben nach dem EDIT stehen hab.
so gesehen ist es hier nur eine Zeile ggü 2 Zeile beim andern Bsp. Allerdings musst du das ganze dann mal auf große Projekte projezieren. Im kleinen Rahmen kannst dir auch 5 einzelne Sortierer ohne interface schreiben, weil du musst ja nur 2 Zeilen ändern, aber im großen komplexen Programm machst du das nicht mehr freiwillig ^^


----------



## 7123 (20. Jun 2008)

ok, alles klar danke für die Erklärung, im größeren Rahmen ergibt das Sinn, aber auf den ersten Blick wird der Sinn des Interface nicht so deutlich. So jetzt muss ich mir noch ein paar Fragen einfallen lassen, damit die 5 Seiten noch erreicht werden


----------



## diggaa1984 (20. Jun 2008)

lol dann mach bitte einer vorher den thread zu 
weil thema is ja nu schon längst verfehlt ^^


----------



## 7123 (20. Jun 2008)

einfachste Grundlagen stimmt ja noch, vielleicht stelle ich ja eine Frage zu Threads demnächst^^


----------



## 7123 (21. Jun 2008)

mir ist noch etwas eingfallen 

noch einmal zum Beispiel von oben:


```
public class Hallo {
int Zahl
Hallo Eins;
public Hallo (int Zahl){
this.Zahl = Zahl;}
}

****************************

public class HalloBezug{
public static void main (String [] args){
Hallo Zwei, Drei;
Drei = new Hallo(0);
Zwei = new Hallo(1);
Drei.Eins = Zwei;  // unklar
Drei = Zwei;}}
```


Ok, also in diesem Programm werden 2 Hallo Objekte in der main erzeugt, soweit klar. Jedoch verstehe ich den Befehl 
	
	
	
	





```
Drei.Eins = Zwei // oder Drei.Eins.Eins = Zwei sofern das auch funktioniert
```
 nicht, ich dachte immer man kann nur Methoden so Schreiben, also "Instanzvariable.Methode". Warum funktioniert aber auch "Instanzvariable.Instanzvariable des Objektes" und was bewirkt dieser Ausdruck genau? Denn es wird ja das Hallo Objekt mit der Variable 1 irgendetwas zugeordnet, hoffe jemand kann mir das noch einmal genau erklären


----------



## diggaa1984 (21. Jun 2008)

sofern du "this.Zahl" verstehst, solltest du auch Drei.Eins verstehen, ist nix anderes. Bedingung ist nur das "Eins" public deklariert ist damit man von aussen drauf zugreifen kann.


----------



## 7123 (21. Jun 2008)

also this.Zahl heißt ja das sich Zahl auf die Variable Zahl, in der Klasse bezieht, dachte ich zumindest  also wird Zwei, dem Eins aus der Klasse Hallo zugeordnet?


----------



## Guest (21. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> also this.Zahl heißt ja das sich Zahl auf die Variable Zahl, in der Klasse bezieht, dachte ich zumindest  also wird Zwei, dem Eins aus der Klasse Hallo zugeordnet?


ja


----------



## diggaa1984 (21. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> also wird Zwei, dem Eins aus der Klasse Hallo zugeordnet?




```
public class Hallo {
int Zahl
Hallo Eins;
public Hallo (int Zahl){
this.Zahl = Zahl;}
}

****************************

public class HalloBezug{
public static void main (String [] args){
Hallo Zwei, Drei;
Drei = new Hallo(0); //Drei.Zahl = 0
Zwei = new Hallo(1); //Zwei.Zahl = 1
Drei.Eins = Zwei;  // Drei.Eins.Zahl = 1
Drei = Zwei;}} //Drei.Zahl = 1
```


----------



## 7123 (21. Jun 2008)

Also kann man die Variablen einer Klasse solange diese public ist auch andere Zahlen zuordnen ohne ein neues Hallo Objekt erzeugen zu müssen, aber wem wird hier die 1 zugeordnet, der Variablen Eins und der Variable Zahl in der Klasse Hallo?

```
Drei.Eins.Zahl = 1
```
oder ist das das gleiche wie

```
Drei.Zahl = 1
```
?


----------



## diggaa1984 (21. Jun 2008)

das ist nich das gleiche, da Drei.Eins unter Umständen ein anderes Hallbjekt ist als Drei
probier es doch mal aus und lass dir ausgeben was da drin steht, dann wirds vielleicht klarer.

es ist auch das denkbar:

Drei.Eins = Drei;
Drei.Zahl = 1;

in dem fall würdest du auch bei Drei.Eins.Zahl die 1 haben. Es kommt also schon drauf an wo was referenziert wird.


----------



## 7123 (21. Jun 2008)

Ok, danke!!!
Neues Thema Applet:  

Bei einem Frame kann man ja individuelle Einstellungen über dessen Sichtbarkeit, Größe, Postion, ... 
treffen, aber ist das auch bei einem Applet möglich. Wenn man z.b. ein Applet erzeugen möchte das an einer
bestimmten Postion ist und dessen Größe fest und somit nicht veränderbar ist, was muss man dann eingeben 
bzw. ist das überhaupt möglich? 
(Ich habe bereits versucht das über google herauszufinden, aber da kommen leider keine brauchbaren Ergebnisse)


----------



## diggaa1984 (21. Jun 2008)

1. kenn mich mit applets nicht aus
2. forumsuche
3. neuen thread, man fragt nich 100 sachen in einem thread  :noe:


----------



## 7123 (21. Jun 2008)

hab einen neuen Thread zu meiner oben genannten Frage aufgemacht


----------



## 7123 (21. Jun 2008)

Ok, ich stelle nur noch Fragen die auch mit dem Thema vereinbar sind   
Angenommen man hat ein Programm, welches eine Zahl hochzählt, z.b. in einem Thread, aber immer noch für Mausklicks offen ist und man bei jeden Mausklick die Zahl in´der 
	
	
	
	





```
public void mousePressed(MouseEvent e)
```
 Methode auf dem Bildschrim ausdruckt, wie ist das realisierbar? Ein Thread kann ja den Wert nicht zurückgeben und wenn ich z.b. in der Paint Methode eine Zählschleife einbaue, kann ich ja keine genau Zeit wie bei einem Thread einstellen und ich kann (sofern es eine Endlosschleife ist) keinen Mausklick mehr ausführen, was tun :?:


----------



## 0001001 (21. Jun 2008)

```
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class ThreadMouseDemo extends JFrame implements ActionListener{
	JLabel txt;
	int zahl = 0;
	public ThreadMouseDemo(){
		Thread blub = new Thread(new MyThread());
		blub.start();
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(new BorderLayout());
		
		JButton button = new JButton("Show current number");
		button.addActionListener(this);
		
		txt = new JLabel();
		this.add(txt,BorderLayout.CENTER);
		this.add(button, BorderLayout.SOUTH);		
		this.pack();
		this.setSize(100, 100);
		this.setVisible(true);
	}
	
	public static void main(String[] args) {
		new ThreadMouseDemo();
	}
	
	public void actionPerformed(ActionEvent e){
		txt.setText(String.valueOf(zahl));
	}
	
	class MyThread implements Runnable{
		public void run(){
			while(true){
				zahl++;
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
```

Auch wenn das Fragen bequemer ist, programmieren lernt man nur durch lesen, selbst versuchen, scheitern und aus seinen Fehlern lernen.


----------



## 7123 (21. Jun 2008)

Danke nochmal, die Idee das so zu machen hatte ich auch, aber ich hatte in der main Thread start und Thread stop direkt nacheinander geschrieben und mich gewundert warum es nicht geht  :shock:


----------



## 7123 (22. Jun 2008)

hm, ich habe noch ein paar Probleme mit den Maus Events und zwar:
Wenn man z.b. nach einem Mausklick erst eine gewisse Zeit warten möchte, z.b. 5s ohne, das ein neuer Mausklick akzeptiert wird bzw. das die Prozedur die hinter diesem Mausklick steht nicht ausgeführt wird gibt es bei mir irgendwie schwiergikeiten. Ich habe den 
	
	
	
	





```
try { 
         Thread.sleep(5000); 
      } catch (InterruptedException e){;}
}
```

Code in das Maus Event eingebaut um für eine gewisse Verzögerung zu sorgen, aber irgendwie ist das Programm trotzdem für weitere Mausklicks offen, obwohl der Alogrithmus nach dem 1. Klicken noch nicht abgearbeitet ist, woran liegt das, bzw. wie kann man das beheben? (diemal habe ich wirklich überhaupt keine Ahnung, hab es über einen if Konstrukt probiert aber das geht nicht)


----------



## Kaini (22. Jun 2008)

Ich hätte zwei Ideen um das Problem zu lösen:
Entweder du setzt eine *Klassenvariable* auf _false_ wärend das noch rennt:

```
if(active) {
    active = false;
    try {
             Thread.sleep(5000);
          } catch (InterruptedException e){;}
    }
    // ...
    active = true;
}
```
Oder du entfernst für die Zeit den Listener wieder. Ich denke die erste Variante ist einfacher .


----------



## 7123 (22. Jun 2008)

genau die erste Variante habe ich auch probiert, nur das ich die Werte 1 und 2 genannt habe (ich glaube das macht nicht den Unterschied). Jedoch geht das nicht, irgendwie wird der Algorithmus nach der Schleife unterbrochen oder kann es sein das die Paint() Methode  wie ein Thread parallel zum Algorithmus nach einem Mausklick abgearbeitet wird, hier mal ein Auszug aus dem Code:


```
public void mousePressed(MouseEvent e)
{
	
	if (s==true  )
	{s=false;
	int v =e.getX()-10;
	int w = e.getY()-10;
	getGraphics().drawOval(v,w,30,30);
	 try { 
         Thread.sleep(500); 
      } catch (InterruptedException f){;}
	
 repaint();
	 s=true;
      }
	 
}
```

in der paint() Methode wird der Bildschrim gelöscht, aber ich kann komischerweise bestimmt 10 kreise auf den Bildschrim zeichen, be´vor der Bildschirm gelöscht wird, Kaini wie meinst du das mit deiner zweiten Variante, oder hat jemand anders noch eine Idee woran das liegt?


----------



## Kaini (22. Jun 2008)

Also die zweite Variante wäre:

```
public void mousePressed(MouseEvent e) {
        // Dein Element (Button was auch immer...)
        button.removeMouseListener(this);
        
        int v =e.getX()-10;
        int w = e.getY()-10;
        getGraphics().drawOval(v,w,30,30);
        try {
            Thread.sleep(500);
        } catch (InterruptedException f) {}
   
        repaint();
        
        // Hier auch
        button.addMouseListener(this);
    }
```
So natürlich musst du statt _button_ dein Element nehmen und statt _MouseListener_ deinen Listener (aber so wie ich das sehe verwendest du eh einen MouseListener)


----------



## 7123 (22. Jun 2008)

geht auch nicht, ich kann immer noch mind. 2 Kreise zeichnen, woran liegt das, ist das bei euch auch so oder mache ich etwas falsch? Wenn ich nach dem MouseEvent den MouseListerner entferne geht nur 1 Klick, aber das bringt ja nichts, sobald ich aber ganz am Ende des Algorithmus den MouseListener wieder hinzufüge geht es wieder nicht, kann es sein das der Algorithmus nicht von oben nach unten abgearbeitet wird?


----------



## Kaini (22. Jun 2008)

Ich glaube ich versteh dein Problem nicht.  ???:L 

Was genau willst du machen bzw. was soll nicht passieren?


----------



## Wildcard (22. Jun 2008)

Ich habe jetzt keine Lust mir die ganzen 5 Seiten durchzulesen, aber von mir folgender Hinweis:
getGraphics ist praktisch immer falsch. Warum, siehe hier:
http://www.java-forum.org/de/topic46550_zeichnen-swing-tutorial.html


----------



## 7123 (22. Jun 2008)

Ok, was ich machen  möchte:

Auf dem Bildschrim soll ein Ziel, z.b. ein Kreis gezeichnet werden (in der Paint() Methode) sobald man nun mit der Maus in das Applet klickt soll ein zweiter Kreis entstehen. Diese beiden Kreise sollen für einen gewissen Zeit sichtbar bleiben und dann verschwinden. Nun erscheint wieder ein neuer Kreis an einer neuen Stelle (durch wiederaufruf der Paint() Methode) und durch einen Mausklick ein zweiter, usw.. Aber wenn 2 Kreise auf dem Bildschrim sichtbar sind soll bei einem weiteren Mausklick kein 3. Kreis entstehen. Etwas verständlicher?


----------



## Wildcard (22. Jun 2008)

Und getGraphics ist dafür falsch. Du darfst nur in paintComponent zeichnen. Welche Kreise du zeichnen willst, musst du dir in einer Datenstruktur merken, die du in paintComponent visualisierst.


----------



## 7123 (22. Jun 2008)

@ Wildcart: Du hast das in deinem Thread zwar sehr schön erklärt, aber wie gesagt ich bin noch Anfänger, deshalb stelle ich mal eine "dumme Frage"  . Muss ich jetzt erst eine ganze Klasse selbst definieren oder stellt Java diese Klasse mitlerweile zur Verfügung (da dein Thread über 1 Jahr alt ist). Was müsste ich jetzt am meinen Beispiel konkret ändern, kann du mir mal bitte ein Beispiel geben wie ich z.b. einen Kreis in der Methode die du sagst erstelle, weil ich irgendwie in deinem Thread die übersicht verloren habe was genau geschieht, hoffe du siehst drüber hinweg das ich nicht ganz durchblicke 

Das kann man doch immer noch schreiben, es bezieht sich doch nur auf getGraphics, oder?


```
public void paint( Graphics g )
    {
    g.drawString( "\"Maja, wo bist du?\" (Mittermeier)", 120, 60 );
  }
```


----------



## Wildcard (22. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> Muss ich jetzt erst eine ganze Klasse selbst definieren oder stellt Java diese Klasse mitlerweile zur Verfügung (da dein Thread über 1 Jahr alt ist).


Keine Ahnung was du damit meinst...
Pseudocode:


```
mouseClicked(MouseEvent e)
{
     kreise.add(new Kreis(e.getLocation());
     panel.repaint();
}
```


----------



## 7123 (22. Jun 2008)

naja ich müsste doch jetzt in deinem Beispiel noch die Klasse Kreise definieren, doer?


----------



## Wildcard (22. Jun 2008)

Entweder das, oder etwas fertiges wie Ellipse verwenden.

Schnell zusammen getippt:

Ein klick erzeugt einen Kreis, nach 5 Sekunden verschwindet er wieder.

```
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.Collection;
import java.util.LinkedList;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;


public class CirclePainter extends JFrame{

	private PaintPanel panel;
	
	public CirclePainter() {
		panel = new PaintPanel();
		panel.setPreferredSize(new Dimension(800,600));
		panel.addMouseListener(new MouseAdapter() {
		
			@Override
			public void mousePressed(MouseEvent e) {
				panel.addShape(new Ellipse2D.Double(e.getX(),e.getY(), 10 , 10), 3000);
			}
		
		});
		add(panel);
	}
	
	public static void main(String[] args) {
		CirclePainter frame = new CirclePainter();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
}

class PaintPanel extends JComponent
{
	private Collection<Shape> shapes = new LinkedList<Shape>();
	
	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2d = (Graphics2D)g;
		super.paintComponent(g);
		for (Shape shape : shapes) {
			g2d.draw(shape);
		}
	}
	
	public void addShape(final Shape shape, int timeToLive)
	{
		shapes.add(shape);
		Timer timer = new Timer(timeToLive, new ActionListener() {
		
			public void actionPerformed(ActionEvent e) {
				shapes.remove(shape);
				repaint();
			}
		
		});
		timer.start();
		Rectangle extendedBounds = new Rectangle(shape.getBounds());
		extendedBounds.grow(1, 1);
		repaint(extendedBounds);
	}
}
```


----------



## 7123 (22. Jun 2008)

Danke erstmal, ganz Blicke ich zwar noch nicht durch, ich werde mich aber nochmal genauer in die Thematik einlesen, welcher Befehl was genau auslöst, da ich das Programm auch als Applet benötige, aber ich weiß zumindest erst mal warum das die ganze Zeit nicht ging :?

Edit.: Habe gerade nach eingabe bei google gelesen das die Methode PaintComponent() nicht in Applets funktioniert, stimmt das oder haben die "keine" Ahnung?


----------



## FArt (23. Jun 2008)

FArt hat gesagt.:
			
		

> *Tüte Chips und Bier hol*
> 
> :bae:
> 
> Wird noch ein interessanter Thread, mal sehen wie lange das noch so geht... ich tippe auf 5 Seiten. Wer bietet mehr?



qed


----------



## 7123 (23. Jun 2008)

@Wildcard: Ich habe das mal so probiert wie du gesagt hast. Wenn ich einen Mausklick Ausführe soll ein JButton erscheinen bzw. geaddet werden, und dann rufe ich die repaint() Methode auf, jedoch wird dann der JButton nicht angezeigt, erst wenn ich die Bildgröße des Applets ändere, bzw. Maximiere erscheint er, ich dachte das sollte gerade dadruch verhindert werden, woran liegt das?


```
public void mousePressed(MouseEvent e)
{getContentPane().add(ButtonA);
repaint();
}
```


----------



## FArt (23. Jun 2008)

Gast 7123 hat gesagt.:
			
		

> @Wildcard



Schade, bin nicht Wildcard, darf nicht antworten.


----------



## Wildcard (23. Jun 2008)

Wenn du einem Container nachträglich Kinder hinzufügst, musst du auf dem Container validate() aufrufen.


----------



## F0rest (24. Jun 2008)

Hi Leute ich hab zwar jetzt nicht alles gelesen, aber da sich hier Leute mit Threads auskennen, dachte ich ich pack meine Frage hier noch rein.

Sei A eine Klasse die Runnable implementiert.
Die Frage ist: Ich sehe, dass es im Prinzip möglich ist 2 Thread instanzen ein und dieselbe Instanz von A zu übergeben. Wo ist aber der unterschied zu dem, dass ich jetzt von A 2 Instanzen bilde und jedem der 2 Threads eine eigene Instanz von A übergebe?

Variante1:

```
public class TwoThreadsTest {
  public static void main (String[] args) {
	SimpleThread t = new SimpleThread();
	SimpleThread u = new SimpleThread();
    new Thread(t, "Villabajo").start();
    new Thread(u, "Villarriba").start();
  }
}
class SimpleThread implements Runnable {

  public void run() {
    for (int i = 0; i < 10; i++) {
      System.out.println(i + " " + Thread.currentThread().getName());
      try {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {}
    }
    System.out.println("DONE! " + Thread.currentThread().getName());
  }
}
```
Variante2:

```
public class TwoThreadsTest {
  public static void main (String[] args) {
	SimpleThread t = new SimpleThread();
    new Thread(t, "Villabajo").start();
    new Thread(t, "Villarriba").start();
  }
}
class SimpleThread implements Runnable {

  public void run() {
    for (int i = 0; i < 10; i++) {
      System.out.println(i + " " + Thread.currentThread().getName());
      try {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {}
    }
    System.out.println("DONE! " + Thread.currentThread().getName());
  }
}
```


----------



## F0rest (24. Jun 2008)

zwei sachen hab ich jetzt schon selber rausgefunden. Der Konstruktor, falls vorhanden, wird dann nur 1 mal ausgeführt. Und die Threads teilen sich dann auch die Instanzvariablen. Komisch, dass die trotzdem parallel laufen ... Aber ich seh schon, lieber sowas nicht machen. Aber seltsam, dass es überhaupt erlaubt ist...


----------



## diggaa1984 (24. Jun 2008)

bei sowas darfst dann gegebenfalls synchronisieren. Wenn also mehrere Threads das selbe Objekt kennen und manipulieren.

edit: huch glaub hab da grad was verwechselt


----------

