# multiThread Problem



## fatfox (26. Mai 2011)

Hi alle,

ich lese gereade MultiThread, aber ich habe kaum etwas kappiert. 

z.B ich habe eine int[] quest = {1,2,3,4,...10}, und ich möchte sie quadrieren, also das Ergbnis soll: int[] answer = {1,4, 9, 16,..., 100}

Meine Idee ist:  Erzeuge zwei Threads, das erste Thread quadriet die erste 5 Zahlen(also: 1,2,3,4,5), und das zweite Thread quadriet die letzte 5 Zahlen (also: 6,7,8,9,10).

Wie kann man das machen? Könnte jemand mir eine konkrete Mustercode geben? Vielen Dank!!!


----------



## Volvagia (26. Mai 2011)

Frei aus dem Kopf:


```
final int[] i = {
		1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};

new Thread() {
	public void run() {
		for(int j = 0; j < i.length; j+= 2)
			System.out.println(i[j] + " - " + Math.pow(i[j], 2));
	};
}.start();

new Thread() {
	public void run() {
		for(int j = 1; j < i.length; j+= 2)
			System.out.println(i[j] + " - " + Math.pow(i[j], 2));
	};
}.start();
```

Allerdings solltest du noch mal von vorne beginnen, da das mehr als einfach ist. Weiß aber garnicht ob es Geschwindigkeitsvorteile bringt, da das erzeugen eines Threads bei so einer Aufgabe wohl leicht auch ausbremsen könnte.


----------



## eRaaaa (26. Mai 2011)

Naja das Beispiel ist ziemlich sinnlos da du nichts am Array veränderst 
Aber generell braucht man hier auch nicht synchronisieren o.ä. Die meisten Überlegungen sind hier wohl in Sachen Mathematik zu machen.....???:L


----------



## fatfox (26. Mai 2011)

Hi Volvagia und eRaaaa,

meine eigentliche Aufgabe ist eine riesen binäre Datei zu lesen. (sie ist c.a. 3 GB).

z.B ich muss Informationen von 1000 User lesen, und ich weiß die genaue Postion von den Users in der binäre Datei. Dann lese ich in der Datei die entsprechende Stelle  die entsprechende Infomation, dann liefere ich die Information zurück in eine "Answer[1000]"

Weil die Datei ziemlich groß ist,(hin und her springen kostet es ganz viel Zeit),  deshalb denke ich, dass es vielleicht schneller wird, wenn ich mehrere Threads gleichzeitig laufen kann. Was sagt ihr dazu?


----------



## fatfox (26. Mai 2011)

Hi Volvagia und eRaaaa,

Ich habe Volvagia's Code einbisschen verändert, um eine Array zu verändern, aber es sieht nicht so gut. Warum? nicht synchronisiert ???? Wie kann man das richtig machen?


```
public static void main(String[] args) {
		final int[] i = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

		new Thread() {
			public void run() {
				for (int j = 0; j < i.length; j += 2) {
					// System.out.println(i[j] + " - " + Math.pow(i[j], 2));
					i[j] = (int) Math.pow(i[j], 2);
				}
			};
		}.start();

		new Thread() {
			public void run() {
				for (int j = 1; j < i.length; j += 2) {
					// System.out.println(i[j] + " - " + Math.pow(i[j], 2));
					i[j] = (int) Math.pow(i[j], 2);
				}
			};
		}.start();

		for (int j = 0; j < i.length; j++) {
			System.out.println(i[j]);
		}
	}
```

output: 

1
2
9
4
25
6
49
8
81
10


----------



## Volvagia (26. Mai 2011)

Du musst mit der Ausgabe warten, bis die Threads fertig sind, sonst wird natürlich nur die bisherige Veränderung ausgegeben -> join.


----------



## SlaterB (26. Mai 2011)

merke dir z.B. die Thread-Objekte in Variablen und rufe vor der Ausgabe in der main-Methode jeweils join() auf,
dann wird auf das Ende der Threads gewartet


----------



## fatfox (26. Mai 2011)

Volvagia hat gesagt.:


> Du musst mit der Ausgabe warten, bis die Threads fertig sind, sonst wird natürlich nur die bisherige Veränderung ausgegeben -> join.



Wie kann man warten? und wie lange? Ich habe eine wait() und eine sleep() Funktion gesehen, aber ich weiß nicht, wie lange so ich warten.... 

Meine originale Aufgabe muss man eine riesen Datei lesen, und ich denke, es ist sehr schwer zu schätzen, wie lange man warten muss...


----------



## Volvagia (26. Mai 2011)

Die Methode join() verwenden. sleep pausiert den Thread x "Zeiteinheiten", wait pausiert den Thread, bis ihm ein anderer wieder aufweckt. Das ist aber ein wenig komplizierter zu benutzen, und wenn nur aufs Beenden gewartet werden soll, ist join auf jeden Fall vorzuziehen. (Vor allem bei mehreren.)


----------



## fatfox (26. Mai 2011)

Hi Volvagia und SlaterB, danke noch mals!!!! join() funktioniert!!!


----------



## eRaaaa (26. Mai 2011)

fatfox hat gesagt.:


> Weil die Datei ziemlich groß ist,(hin und her springen kostet es ganz viel Zeit),  deshalb denke ich, dass es vielleicht schneller wird, wenn ich mehrere Threads gleichzeitig laufen kann. Was sagt ihr dazu?



Mhm, was genau machst du denn mit den Daten die du liest? Bearbeitest du die noch aufwändig? Und liest du nur aus einer Datei auf einer (normalen) Festplatte? :reflect:
Das mit dem Springen verstehe ich noch nicht ...


----------



## fatfox (26. Mai 2011)

eRaaaa hat gesagt.:


> Mhm, was genau machst du denn mit den Daten die du liest? Bearbeitest du die noch aufwändig? Und liest du nur aus einer Datei auf einer (normalen) Festplatte? :reflect:
> Das mit dem Springen verstehe ich noch nicht ...



Hi eRaaaa, 

ja, ich lese Datei aus eine normale Festplatte (Gibt es welche besondere Festplatte???). Ich lese mit dem RandomAccessFile(), da RandomAccessFile eine Funktion "seek(long position)" hat, kann man recht einfach die entsprechende Information finden, solange man weiß, wo liegt die Information. Problem ist dass ich zu viel und zu oft lesen muss, deshalb möchte ich die Geschwindigkeit erhöhen.

Ich hole die Information von der Datei aus, vergleichen und soweit. Ich mache etwas wie Datamining für meine Diplomarbeit. Die Datei ist oft sehr groß, deshalb ist es unmöglich in meine Ram zu speichern. 

Sonst habe ich keine bessere Idee dafür.(mysql ist wahrscheilich langsamer als seek()). Wie machst du das normalerweise?


----------



## eRaaaa (26. Mai 2011)

seek kenne ich natürlich, ich verstehe nur noch nicht wozu du das brauchst, wenn du wie beschrieben eh alle 1000Zeilen/User was auch immer in ein Array der Größe 1000 schreiben willst. Oder habe ich da missverstanden, das war meine Frage sorry. Dann kannst du doch gleich sequentiell lesen und sparst dir das seek?! 

Vllt. hätte ich auch *eine* Festplatte/Lesekopf dick schreiben sollen 
Denke nicht dass das viel bringt....(denke eher das Gegenteil wird erreicht ?! oder..?)


----------



## fatfox (26. Mai 2011)

eRaaaa hat gesagt.:


> seek kenne ich natürlich, ich verstehe nur noch nicht wozu du das brauchst, wenn du wie beschrieben eh alle 1000Zeilen/User was auch immer in ein Array der Größe 1000 schreiben willst. Oder habe ich da missverstanden, das war meine Frage sorry. Dann kannst du doch gleich sequentiell lesen und sparst dir das seek?!
> 
> Vllt. hätte ich auch *eine* Festplatte/Lesekopf dick schreiben sollen
> Denke nicht dass das viel bringt....(denke eher das Gegenteil wird erreicht ?! oder..?)



"Sequentiell lesen" meinst du mit dem "Skip( )"??? Ich habe getestet, dass "seek()" genau so schnell wie "skip()" ist. wenn ich skip benutze, dann kann ich nicht zurück springen, ich muss den user sortieren von vorne nach hintern lesen. 
Also z.B

Ich muss Information über 1000 user holen: wieviele Bücher hat dieser User gelesen, und welche bewertungen hat er gegeben...
ein User kann sehr viel Bücher gelesen und bewertet.
Ich habe über 1 millionen User.

Deshalb ist von einem User zu einem anderen User springen dauert sehr lange Zeit.


----------



## Volvagia (26. Mai 2011)

Wie sieht die Datei den aus?
Wenn ich z. B. etwas abspeichere, ist es in etwa so:


```
Username;Data1;Data2;Data3
Username;Data1;Data2;Data3
```

In so einen Fall kann man einfach mit dem BufferedReader durchfahren, und am ";" splitten.


----------



## fatfox (26. Mai 2011)

Volvagia hat gesagt.:


> Wie sieht die Datei den aus?
> Wenn ich z. B. etwas abspeichere, ist es in etwa so:
> 
> 
> ...



Ich habe eine binäre Datei, sie sieht so aus:
[user1][Data][Data]....[user2][Data][Data]...

Ich habe noch eine Array erzeugt: "int [ anzahl der Users] position". Diese "position" Array sagte mir die genaue Stelle von jedem User. Wenn ich um einen bestimmte User suchen muss, dann gucke ich zuerst seine Position, dann mit "RandomAccessFile.seek()" lande ich direkt zu den user. Das ist sehr effizient. Ich vermute das ist noch schneller als MySQL, aber trotzdem nicht schnell genug. Um Information von 1000 User zu bekommen, dauert es c.a 3-5 seconds.

Ich muss fast halb millionen mal 1000 user rufen. Das dauert mehr als eine Woche..., deshalb habe ich multiThread gedacht. :-(


----------



## Volvagia (26. Mai 2011)

Dabei würde ich auf jeden Fall auf eine Datenbank setzen. Mit Java auf H2, der Syntax ist sehr ähnlich zu MySQL. Es wird aber u. a. kein Server benötigt.


----------



## fatfox (26. Mai 2011)

Volvagia hat gesagt.:


> Dabei würde ich auf jeden Fall auf eine Datenbank setzen. Mit Java auf H2, der Syntax ist sehr ähnlich zu MySQL. Es wird aber u. a. kein Server benötigt.



Hi Volvagia, danke für das Tips! Ich probiere mal H2, wenn fertig, dann reporte ich mal das genaue Ergebnis!  (Ich habe eine andere DantenBank  HDF5 probiert, aber meine Methode ist schneller. MySQL habe ich früher benutzt, aber irgendwie fühle ich immer zu langsam. )


----------

