Multithreading

Status
Nicht offen für weitere Antworten.

PhantomXXL

Bekanntes Mitglied
ALso ich hab da mal was von Java und Multithreading gehört, was heisst das exakt?

Kann ích dann zb aus einem Programm gleichzeitig ein odere mehrere andere/s Programm mehrfach aufrufen, wobei diese dan paralell Daten auswerten, und das Hauptprogramm wartet bis alle Programme ihre Daten zurückgeliefert haben? Oder muss ich vom Hauptprogramm aus diese Daten sequentiell senden, verarbeiten lassen und wieder bekommen?

Im Grunde hab ich ein Servlet das etwas verarbeitet, jedoch auf mehrere andere Servlets (bwz auchandere Server) zugreift. Wenn ich jedoch einen nach dem anderen Verarbeiten muss dauert dies leider ein wenig. Daher die Idee im Hauptprogramm zu splitten und warten bis eben diese Daten wieder da sind, so das die anderen Server gleichzeitig rechnen.

Schematisch sieht das dann etwa so aus:
Code:
...
split 1 {
 send_something
 get_something
}
split 2 {
 send_something
 get_something
}...
split n {
 send_something
 get_something
}

wait_until_all_split_ready
...

dabei sollten eben alle splits zugleich ausgeführt werden (soweit dies möglich ist) da zwischen den send und get daten eingie zeit liegt (verbindung zum server aufbauen, daten senden, warten bis server daten verarbeitet, rückdaten auslesen).

Solles es nicht möglich sein, wäre ich trotzdem über ne aufklräung vom begriff Multithreading dankbar :)
 
K

klom

Gast
Nun ja, über Threads (Klasse Runnable siehe API) müsste das doch möglich sein. Ich kenne mich zwar nicht mit Netzwerkporgrammierung aus, aber in Java kann man verschiedene Threads starten, die dann bestimmte Prozesse nebeneinander ausführen. Daher auch die Bezeichnung "multithreading".
 

Bleiglanz

Gesperrter Benutzer
So in etwa, verwechsle aber nicht

Mutlithreading (auf einer Maschine)

mit

Remoteing (auf verschiedenen Rechnern, was GANZ was anderes)


Abhängig von der JVM und dem OS könnte auf einem Rechner mit mehr als einem Prozessor evtl. gleichzeitig in verschiedenen Threads gearbeitet werden, bei einer Maschine mit einem Prozessor ist die Aufteilung von Aufgaben auf Threads immer LANGSAMER als wenn man alles der Reihe nach macht

=> Multithreading verwendet man meistens, um die "Responsiveness" zu verbessern (d.h. ein User soll nicht vor einem blockierten Programm sitzen während auf IO gewartet wird) oder um z.B. mehrere Anfragen "quasi-gleichzeitig" zu bearbeiten (z.B. Webserver)

Bedenke:

* Dein Servlet lebt eh schon in einer Multithreaded-Umgebung

* Ein Servlet kann machen was es will, auf einer 1-Prozessor-Maschine hat es überhaupt keinen Sinn, Aufgaben an Threads zu vergeben [es muss ja dann gewaretet werden, bis alles fertig ist und am ende wird z.B. eine HTML-Seite an den Aufrufer geschickt]
 

PhantomXXL

Bekanntes Mitglied
=> Multithreading verwendet man meistens, um die "Responsiveness" zu verbessern (d.h. ein User soll nicht vor einem blockierten Programm sitzen während auf IO gewartet wird) oder um z.B. mehrere Anfragen "quasi-gleichzeitig" zu bearbeiten (z.B. Webserver)

Meine Servlets liegen auf mehreren Web-Servern, dazu kommen noch einige Externe Server. Und eben das mit dem blockierten Programm ist genau das was ich meine :) Servlet auf Server A startet Servlet auf Server B, muss aber auf IO warten, und könnte derzeit auch Servlet auf Server C und Daten von Externen Servern holen (die externen gehören nich mir, aber im grunde eben selber ablauf), da sowieso bei jedem auf das IO gewartet werden muss (hab ich das nicht, wenn auch umständlich beschrieben?).

Wenn jetzt jeder Server 1-2 Sekunden braucht zwischen in- und output summiert sich das schon auf einige Sekunden, und wer will beim Surfen schon so lange warten bis die Seite aufgebaut ist?
 

Bleiglanz

Gesperrter Benutzer
na dann nimm threads, servletA soll praktisch nur eine Art Dispatcher sein für echtes "verteiltes" REchnen?


Servlet A auf Server A aufgerufen

-> starte Thread um von ServletB auf ServerB was zu holen
-> starte Thread um von ServletC auf ServerC was zu holen
....
-> starte Thread um von ServleX auf ServerX was zu holen

sammle alles ein [etwas tricky] und fertig
 

PhantomXXL

Bekanntes Mitglied
SO hab jez bissle Rumprobiert und kam dabei leider zu nem mir nicht erklärbaren fehler. Hier erstmal das Programm.

Code:
public class ProzessThread extends Thread {
	//Nummerierung für Laufende ProzessThreads	
	static private int threadrun;
	//Eigene Nummer
	private int thisrun;
	
	//Ist die Verbindung erledigt
	private boolean done;
	//Wurden die Daten bereits verwendet
	private boolean datasend;
	//Die Daten
	private String data;
	//Instanz des aufrufenden Prozesses
	private Prozess prozess;
	//URL von der Daten gelesen werden sollten
	private String URL;

	ProzessThread(Prozess getprozess, String getURL) {
		thisrun=threadrun++;
		prozess = getprozess;
		synchronized(prozess) {
			prozess.threadsrunning++;
		}
		done=false;
		datasend=false;
		data="";
		URL=getURL;		
		start();
	}

	public boolean isdone(){
		return done;
	}
	
	public boolean isdatasend(){
		return datasend;
	}
	
	//daten ans hauptprogramm zurückgeben und thread unterbrechen
	public String getdata() {
		if(done) {			
			datasend=true;
			synchronized(prozess) {
				prozess.threadsrunning--;
			}
			interrupt();
			return data;
		}
		return null;		
	}
	
	public void run() {
		prozess.echodebug("interface connect ("+thisrun+")");
		
		// Verbindung aufbauen und daten holen
		CMSConnection con = new CMSConnection(URL);
		if ( con.doWork() ) {
			data = con.getContent();
		}
		
		done=true;
		setDaemon(true);
		prozess.echodebug("interface close ("+thisrun+")");		
		while(!isInterrupted()) {
		}		
	}	
	
}

Der Teil wird im Hauptprogramm aufgerufen
Code:
ProzessThread p=new ProzessThread(this,"http://localhost/interface/Interface?schnitt=1&makro=1"+debug);
		while( !p.isdone()) {
			// machama ga nix
		}
		String data = p.getdata();

Nun Probleom ist das er irgendwo zwischend en beiden echodebugs im run stecken bleibt. das komisch daran aber ist das wenn ich den code dazwischen rein im Hauptprogramm anstatt der Instanz der ProzessThreadklasse aufrufe funktionierts. Was ja eigentlich heisst hier is das Problem nicht.

Code:
		String data="";
		CMSConnection con = new CMSConnection("http://localhost/interface/Interface?schnitt=1&makro=1"+debug);
		if ( con.doWork() ) {
			data = con.getContent();
		}

ausserdem startet der eclipse (mit dem ich tomcat+console laufen hab) sofort den debugmodus aber zeitgt nichts an was zu debuggen wäre, die echodebugs sind aliases für system.out.println gehen halt bis zu dem einen genannten, und geht dabei langsam aber sicher zu grunde (wird immer langsamer bis eclipse keine rückmeldung mehr laut windows taskmanger liefert)

ps: evtl gehört das ganze nun in en anderes forum, weil anfängerfrage isses ja nicht mehr wirklich so :)
 

Bleiglanz

Gesperrter Benutzer
lass das mit dem start() im Konstruktor!

warum als Dämon? Du willst doch eh warten bis der Thread fertig ist!

du bist fertig (done=true) und schickst den Thread dann in eine Endlosschleife? wozu?? fertig ist fertig, der Thread hört eben auf wenn er seine Arbeit beendet hat
 

PhantomXXL

Bekanntes Mitglied
dachte die sind dan tot wenn sie aus der run raus sind? so hab ichs halt rausgelesen.

wioes nicht start im kosntruktor? es ist 100% beabsichtigt das er auf jeden fall den thread startet sobald er existiert

und dämon, naja mein hintergedanke dazu erübrigt sich sowieso mti dem done *g*
 

PhantomXXL

Bekanntes Mitglied
hab mal das dämon und die schleife entfernt, scheint tatsächlich das problem gewesen zu sein ... aber mit dem start is anch wie vor beabsichtigt ...
 

Bleiglanz

Gesperrter Benutzer
dachte die sind dan tot wenn sie aus der run raus sind? so hab ichs halt rausgelesen.

ja und? lass ihn doch tot sein wenn er mit der Arbeit fertig ist?

mach den Start von aussen! falls dein Gebilde noch nicht 100%ig initialisiert ist [und das kann ja im Konstruktor durchaus der Fall sein] ist es problematisch wenn du innerhalb des Konstruktors start()est
 

PhantomXXL

Bekanntes Mitglied
ich starte eben erst am ende des konstruktors, dort wird alles initalisiert, ich glaub kaum das der im kosntruktor zu multithreaden beginnt, sondern dort brav eines nach dem anderen abarbeitet.
habs aber dahingehend geändert das ich noch ne boolean übergib ob er im konstruktor(ende) starten soll oder nicht, wenns probleme gibt setz ich das einfach auf false :p und schau ob das wirklich das problem war

und das mit dem tot: ne stunde bevor ichd as schrieb wusste ich nichtmal das es die klasse thread gibt. und wenn man dan schnell paar beispiel und texte liest, passiert das man falsch auffasst *g*
 

PhantomXXL

Bekanntes Mitglied
wie erstell ich zu dem ganzen ne liste das ich n-threads starten kann und danach diese eben durch die liste wieder auslesen.

meine erste idee war ja recht einfach, aber wirft nen nullpointer exception, is ja uch klar wiel ich ich nicht weis wie ich die liste sonst initalisieren soll...

Code:
		List ptlist = null;
		ptlist.clear();		
		boolean newmakro=false;
		do{
			ptn=(new ProzessThread(this,"http://localhost/interface/Interface?schnitt=1&makro=1"+debug,true));
			ptlist.add(ptn);
		}while(newmakro);

problem dürfte wohl nur die erste zeile sein. weil schon in der zweiten dad nullpointerexception geworfen wird.
 

PhantomXXL

Bekanntes Mitglied
wär ja zu schön wenn das problem nu vorbei wär *g*

erstma ne kopie aus meiner console:
Code:
Debug Prozess 4(0): Thread 8 interface connect
Debug Interface 8(0): start
Debug Interface 8(0): start lesen
Debug Prozess 4(0): Thread 9 interface connect
Debug Interface 9(0): start
Debug Interface 9(0): start lesen
Debug Interface 9(16): SchnittURL: [url]http://192.168.168.50:10000[/url]
Debug Interface 9(16): SchnittURL: [url]http://192.168.168.50:10000[/url]
Debug Interface 9(31): macro read
Debug Interface 9(31): macro read
Debug Interface 9(47): macro funktion
Debug Interface 9(47): macro funktion

was daran lustig ist: der String debugstring wird dabei für die ausgabe verwendet ( "Debug Interface +"run ).
run ist die int var, die jeweils die laufnummer präsendtiert ist keine static, genausowenig wie der string, trotzdem wird die wenn sie erhöht wird in beiden servlets verwendet.

prozess startet nun 2 mal das interface, interface startet dran brav und arbeitet weiter...
aber wenn dan mal umgeschalten wurde und das zweite interface auch verarbeitetet wird, muckts auf:
die zweite schnitturl, wie auch die anderen einträge danach, gehört je eine eigentlich zum interface 8, nicht 9.
genauso denke ich wird die laufzeit einfach überschrieben (die zahl in klammer ist laufzerit des servlets in milisekunden), das ist aber halt schwer zu sagen.

noch zu rübersicht die variablen und funktionen:
Code:
public abstract class EasyServlet extends HttpServlet {
...
	static private int runs;
	private int run;

	static private long startserver;
	private long startservlet;

	private String debugstring;
...
	public final void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
		startservlet=System.currentTimeMillis();	
		synchronized(this) {		
			run=runs++;
		}
		...
		try {
			doProzess(request, response);
		} catch( SQLEx...
		...
	}

	protected abstract void doProzess(HttpServletRequest request, HttpServletResponse response) throws SQLException;

...

	public int getRun() {
		return run;	
	}
	
	public void setDebugString(String setstring) {
		debugstring = setstring;
	}

...
}

Code:
public class Interface extends EasyServlet {
	private int thisrun;

	protected void doProzess(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		thisrun=getRun();
		setDebugString("Debug Interface "+thisrun);
		echodebug("start");
		...
	}
}

mir ist einfach nicht klar wieso im debugstring nach dem start des zweiten servlets plötzlich im erstena uch das selbe steht, ist doch ne eigene istanz von der klasse easyservlet, es wäre mir klar wenns ne static variable is, was numal genau nicht ist.
 

Bleiglanz

Gesperrter Benutzer
was machst du denn jetzt wieder?

du wolltest doch EIN servlet das sich mehrere sachen von woanders her holt, warum schreibst du jetzt sowas, das sieht aus wie ein Servlet das von MEHREREN angepostet werden soll?

was soll doProzess denn machen??
 

Bleiglanz

Gesperrter Benutzer
mir ist einfach nicht klar wieso im debugstring nach dem start des zweiten servlets plötzlich im erstena uch das selbe steht, ist doch ne eigene istanz von der klasse easyservlet, es wäre mir klar wenns ne static variable is, was numal genau nicht ist.
nur zu deiner INFO: der ServletContainer erzeugt eine unbekannte Zahl von Instanzen, die in einem Pool liegen und die er mutlithreaded (!) ggf. mit einem Request füttert

dein debugstring ist zwar private, wird aber deswegen unter Umständen bei gleichzeitigen Requests gemeinsam verwurstet

d.h. member variablen von servlets verhalten sich fast wie static

BTW: lern erst mal die Grundlagen, bevor du dich an Servlets machst, die selber eigene Threads verwalten sollen
 

PhantomXXL

Bekanntes Mitglied
doProzess is einfach der teil der doget/dopost mit aufgaben übernimmt in der unterklasse, da dopost einige aufgaben erledigen soll die es immer macht.

und es is halt im test so das sich alles lokal befindet.

um nochmal die struktur zu beschreiben:
Prozess startet mehrere Threads die jeweils eine Verbindung zu den Interfaces herstellen. Die Interface (können auf verschiedenen Servern liegen, welcher verbunden wird entscheidet prozess) verarbeiten Daten aus MySQL Datenbank und XML von diversen Servern (in dem fall isse halt zweimal der selbe, weil wir in der testumgebung im büro numal nicht ettliche pcs aufstellen können).
klar kann es auch im echtbetrieb dan vorkommen das sich zweimal ein interface vom selben server aufruft, aber speziel bei mehreren zugriffen sowieso.

nur wozu mach ich static und nicht static variablen, wenn scheinbar alle static sind... das ist jetzt mein Problem und das mach ich grad :p

EDIT: grundlagen kenn ich ja einige, aber deshalb weis man nicht alles, speziel wenns ins komplexere geht
 

Bleiglanz

Gesperrter Benutzer
verzichte auf die statics

-> doGet und doPost an doProzess weiterleiten

-> alle benötigten variablen lokal halten? wozu willst du statics?

-> in doProzess startest du dann deine Threads, wartest bis alle fertig sind und schickst das endergebnis...

aber quäl dich erstmal nicht, machs erstmal ohne threads (hol den schotter nacheinander); sonst hast du ja gar keinen vergleich, ob dein Multithreaded-Ansatz Performancemässig irgendwas bringt...
 

PhantomXXL

Bekanntes Mitglied
hab mir jez ne struktur klasse gebaut, die alle daten enthält und halt ab dem dopost an doprozess usw rumgeschubst wird. so gehts nu. is halt noch nicht sehr elegant, weil ich ma shclicht alles public machte und direkt auf die vars zugreife. aber egal *g*

und der sinn am multithread is performance mässig nach wie vor das ich verschiedene server ansteuere, die wiederrum verschiedene server ansteuern. wenn jez bie jedem aufruf im prozess warte bis die verbindung zu nem interface da is das wiederum zu nem anderen server (mysql, xml, oder woher auch immer die daten kommen) aufbaut, dan verarbeitet ... das dauert einfach :)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
buzzlightyeah multithreading Java Basics - Anfänger-Themen 4
sserio Frage zu Threading - Multithreading Java Basics - Anfänger-Themen 2
I Threads Multithreading, Producer/Consumer, notify() Java Basics - Anfänger-Themen 6
M Mehre Dateien parallel kopieren mit Multithreading Java Basics - Anfänger-Themen 8
kilopack15 Verzweiflung wegen Berechnung mit Multithreading Java Basics - Anfänger-Themen 1
P Multithreading in Java Java Basics - Anfänger-Themen 9
N Threads Read-Modify-Write Problem bei Multithreading (philosopher dining problem) Java Basics - Anfänger-Themen 5
R Threads Multithreading Java Basics - Anfänger-Themen 15
Z Verständnisfrage zum Multithreading Java Basics - Anfänger-Themen 3
T Threads MultiThreading NullPointerException Java Basics - Anfänger-Themen 7
K Frage bzgl. Multithreading Java Basics - Anfänger-Themen 5
B Multithreading und eigene Queue entwickeln Java Basics - Anfänger-Themen 3
C Multithreading, Methoden sichern Java Basics - Anfänger-Themen 5
P Hilfe bei MultiThreading; Einige Fragen. Java Basics - Anfänger-Themen 14
S OOP Multithreading Java Basics - Anfänger-Themen 5
B Multithreading Java Basics - Anfänger-Themen 5
0din Multithreading und stop Java Basics - Anfänger-Themen 5
P Singletons und Multithreading Java Basics - Anfänger-Themen 11
U Anfängerfrage - Multithreading Java Basics - Anfänger-Themen 8
H Multithreading Java Basics - Anfänger-Themen 7
M Multithreading Java Basics - Anfänger-Themen 18
I Multithreading (Prüfungsvorbereitung) Java Basics - Anfänger-Themen 6
G UI friert bei Multithreading ein Java Basics - Anfänger-Themen 3
J Multithreading mit einer TextArea Java Basics - Anfänger-Themen 29
JFeel-x Multithreading in awt Java Basics - Anfänger-Themen 2
L NullpointerException wegen wahrscheinlichem Multithreading Java Basics - Anfänger-Themen 4
Z Multithreading Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben