# Threads parallel zur SQL Abfrage



## charlie86 (22. Jul 2008)

Hallo!

ich habe eine kleine Datenbank im Internet, worauf ich mit einem Java Programm zugreifen möchte. Das Auslesen geht dabei einwandfrei. 
Da die Bearbeitungszeit allerdings ab und zu mehrere Sekunden kostet möchte ich parallel eine Animation abspielen. (Sanduhr oder Ähnliches) Allerdings habe ich das Problem, das die Anfrage mit executeQuery(..) das komplette Programm still legt, bis die Daten angekommen sind.

Also hab ich versucht die Anfrage mittels Thread parallel laufen zu lassen, das hat nicht geklappt. Danach die Anfrage und Animation in gesonderten Threads behandeln, aber alles was ich versucht hab führte immer zum selben Ergebnis: Alles Blockiert, bis die Daten da sind...

Ich weiß wirklich nicht mehr weiter, mit Threads hab ich normalerweise nicht viel zu tun, kann mir vielleicht jemand weiterhelfen?

Danke!


----------



## parabool (22. Jul 2008)

kann vielleicht sein daß die Threads nicht gestartet wurden? 
Die DB-Operationen folglich nicht nebenläufig ausgeführt wurden.
Also z.B die start-Methode nicht aufgerufen...
Ohne Code kann man da schwerlich etwas sagen.


----------



## charlie86 (22. Jul 2008)

danke für die schnelle antwort.. also sobald executeQuery ausgeführt wurde geht alles wieder wie gewohnt parallel (durch flags getestet)

hier mal der sql teil. Es ist eine Innere Klasse, der rest dient nur zur initialisierung und korrekter ausgabe


```
class SQLQuery extends Thread {
		public void run() {

			System.out.println("start");  // Flag1

			MySQL conn = new MySQL();
			ResultSet res = conn
				.executeQuery("SELECT name, points, size_x, date FROM highscore"
							+ " ORDER BY points DESC, date");
			
                       System.out.println("query complete");  // Flag2
			
			ArrayList<String[]> list = new ArrayList<String[]>();
			String[] row = new String[5];

			[......]  // Hier werden die Daten vom Resultset etwas verarbeitet 


			} catch (SQLException e) {
				System.out.println(e);
			}
			conn.closeConnection();

			rowData = (String[][]) list
				.toArray(new String[list.size()][]);
			
			System.out.println("stop");          // Flag 3
			t.stop();
		}
	}
```

der aufruf:

```
Thread t;
t = new Thread(new SQLQuery());
t.start();
```

Folgendes passiert dann im Programm:
-Flag 1 wir ausgegeben, der 2. Thread macht auch brav seine ausgabe
-Beide Threads hängen, Flag 2 ist noch nicht ausgegeben
-Kurze zeit später wird Flag 2 ausgegeben, Thread 2 macht auch wieder weitere Ausgaben
-Flag 3 wird erreicht, der Thread stoppt


//----------------------

EDIT:

ich konnte das Problem lösen, hat sich von selbst erledigt. Ein Thread reicht vollkommen aus. Danke für deine Hilfe.


----------



## parabool (23. Jul 2008)

Du übergibst  den Thread-Konstruktor also _new Thread(new SQLQuery())_ ein weiteres Thread-Objekt.
Der erwartet aber ein Objekt vom Typ Runnable (Interface)

Deine Klassendefinition brauchst du nur in der 1.Zeile zu ändern also statt

```
class SQLQuery extends Thread
```


```
class SQLQuery implements Runnable
```


Ich weiss nicht ob es daran liegen könnte (immerhin liefern beide Threads Ausgaben).
Und die Klasse Thread implementier auch Runnable. (Daher auch keine Fehlermeldung)

Da es eine einzige Abfrage ist, kannst du auch nicht ein Thread.sleep einfügen ,das den 2 Thread ev. die Möglichkeit
geben würde seine Ausgaben zu machen.

Du könnest ev. noch versuchen die Priorität deines 1. Threads zu reduzieren.


EDIT: hab gerade gesehen dass du das problem gelöst hast. klar reicht 1 Thread.
woran lags nun?

Egal-ich schicke den post trotzdem ab.

 :wink:


----------



## charlie86 (27. Jul 2008)

sry für die verspätete antwort

zunächst zur erklärung: das war als highscore konzipiert: die daten sollten von der datebank geholt werden und dann anschließend in einer tabelle in einem extra panel wiedergegeben werden. während dem zugriff sollte eine dynamische animation laufen. Das hauptprogramm, von dem die threads aktiviert wurde hat von jFrame geerbt.

also hatte ich den thread mit der ladeanimation zunächst gestartet, danach den mit dem datenbankzugriff. Da hatte ich aber das problem das die methode, von wo aus die threads gestartet wurden, natürlich weitergelaufen ist und ne nullpointerexception ausgelöst hat. (ich weiß, schlechter stil, hab da aber nicht drüber nachgedacht, verzweifelt alles mögliche schon getestet)

also hab ich das hauptprogramm durch ne schleife in ein wartezustand geschickt, bis die datenbankoperation fertig war.
dazu ein flag was die schleife abbricht. (gibts eigentlich ne möglichkeit das hauptprogramm "schlafen zu legen" und dann mit notify() oder so aufzuwecken? )

naja der fehler lag daran, dass das hauptprogramm geblockt war, die animation wurde aufgerufen und ist gelaufen, wurde aber nicht angezeigt: warum? weil es im hauptprogramm nie einen repaint gegeben hat, erst wieder, als die schleife fertig war.

Sowas einfaches, aber da muss man erstmal drauf kommen!

eine komplett andere, und besser durchdachte konstruktion hats dann gelöst.


EDIT:

wo liegt eigentlich genau der unterschied zwischen:


```
implements Runnable
```
und

```
extends Thread
```

klar, das eine ist ein interface, das andere eine klasse, aber beide werden ja zur nebenläufigkeit benutzt. Ich benutz immer die extends variante, mit der anderen hatte ich ab und zu kleinere probleme. (liegt wohl an meinen eher geringen Thread erfahrungen)

gruß


----------



## SlaterB (28. Jul 2008)

extends Thread geht nicht, wenn man eine andere Basisklasse braucht,
z.B. 
class GUI extends JFrame implements Runnable,

ist aber oft ein Luxux-Problem, man kann fast immer auch zwei separate Klassen verwenden


----------

