aus mehreren Programmen ein Programm mit Threads machen

  • Themenstarter Themenstarter Fritz
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
F

Fritz

Gast
hallo,

ich habe eine verteilte Anwendung geschrieben, bei dem ursprünglich jedes Programm in einer eigenen JVM gestartet werden sollte. Weil das aber zum Testen recht aufwendig ist, jedes mal das gleiche Programm mehrere Male zu starten, wollte ich diese Programme nun in Threads packen (In jedem einzelnen Programm kommen sonst keine Threads vor). Urspünglich habe wurde das einzelene Programm wie folgt gestartet:

Code:
public static void main(String[] args) {
        //Start 
        Init calc=new Init();
        calc.Go();   
}

Um nun alles in einem Programm laufen zu lassen, habe ich einfach die Klasse Init() als Runable versehen und in die run()-Methode nur die Methode Go() reingepackt, also:


Code:
public class Init extends CalcChange implements Runnable{
     public void run() {
        this.Go()
    }

Nun will ich das ganze so starten in main():


Code:
Thread t2 = new Thread(new Init()); 

     

        for (int i = 1; i < 5; i++) {
            new Thread(t2).start();
        }

Es funktioniert grundsätzlich auch, nur werden Variablen usw. überschrieben. Es wird auch sehr viel mit Vererbung gearbeitet. Meine Frage: Gibt es einen einfachen Weg, das Ganze in Threads zu packen, ohne das Programm wesentlich zu ändern. Es sollen einfach 5 eigene Programme laufen, ähnlich einem fork in C. Synchrinsation ist auch nicht nötig. Kann jmd helfen?

Danke
 
Wenn ich mich nicht sehr täusche, dann sind die einzigen Variablen, die da überschrieben werden können, statische Variablen, und wer die verwendet, um Zustände zu speichern, ist selbst schuld (->Mach' sie nicht-static).
Andernfalls müßtest du das Problem genauer beschreiben.
 
Hi,

eine besondere Eigenschaft von Threads ist, dass sie miteinander den gleichen Speicherraum teilen (Heap), wogegen Prozesse einen eigenen Speicherraum erhalten, spätestens wenn das erste Mal schreibend darauf zugegriffen wird ("copy on write"). Es ist also kein Wunder, dass die Threads in der Lage sind, sich gegenseitig "Variablen" zu überschreiben. Neben den mit static markierten Variablen, die im Heap gespeichert werden, werden auch alle mit new angelegten Objekte dort gespeichert, aber damit die gegenseitig überschrieben werden können, wird natürlich eine Referenz auf das Objekt benötigt.

Was Du eigentlich haben möchtest, ist ein fork(), aber das ist die UNIX-spezifische Methode der Prozess-Erzeugung. Am nächsten dran scheint java.lang.Runtime.exec(String), das einen neuen Prozess erzeugt. Runtime.exec() entspricht am ehesten pipe(), und ist nicht das, was Du haben willst. Runtime.exec() ruft eigentlich nur ein externes Programm auf. Es ist wahrscheinlich am einfachsten, wenn Du Dir ein Shellskript/eine Batchdatei schreibst, das/die das Programm x-mal für Dich startet.

Im übrigen gilt natürlich das, was Marco13 gesagt hat, aber ich gehe mal davon aus, dass es zu spät ist, Dein Programm "mal eben" threadsicher zu machen ... kannst ja mal drauf hin arbeiten 😉
 
Nun, wenn es keine statischen Variablen gibt, dann sind die Objekte, die dort mit
Init calc=new Init();
ja bildlich gesprochen "die Wurzeln von Bäumen" ("Objekthierarchien"). Wenn jedes "Init"-Objekt ein Field
Code:
class Init
{
    Data someData = new Data();
}
enthält, liegen dieses "Data"-objekte zwar alle im gleichen Speicher, und es sind auch immer die gleichen Objekte, aber es sind eben nicht dieselben. Überschrieben werden kann dort nichts. Wenn man sich aber das Leben leicht machen wollte, und sowas geschrieben hat wie
Code:
class Init
{
    public static Data someData = new Data();
}
"weil das so praktisch ist, weil man da so leicht von überall drauf zugreifen kann", dann ist das natürlich immer ein- und dasselbe Objekt, und dann kracht's...
 
Hallo,

vielen Dank für die Antworten. Es war nur eine Var. static und nachdem das geändert wurde, lief es auch nicht.

Es handelt sich um eine Client/Server Applikation. Statt viele Clients zu starten, sollen alle in ein Programm gebracht werden, bei dem jeder Client einen Thread darstellt. Selbstverständlich haben dann auch alle Variablen eigene Werte.

Was ich an Euren Antworten nicht so ganz verstanden habe: Ist das grundsätzlich überhaupt möglich? Und was heißt thraedsicher machen? Vor jede Klasse ein synchronized() setzen? Könnte das helfen?

Danke
 
Grundsätzlich ist das möglich. Wenn man 10 Programme hat, mit 10 main-Methoden, dann kann man sich eine Klasse basteln, die jede einzlene main-Funktion in einem eigenen Thread startet, und wenn es keine statischen Variablen gibt dann laufen die 10 Programme so, als ob sie einzlen laufen würden (sie wissen genaugenommen nichtmal was voneinander). (Wenn ein GUI dabei ist, verwischt das ein bißchen, aber sollte keine grundsätzlichen Probleme ergeben).

Viel problematischer ist, wenn du von Client/Server sprichst, die Frage, wie denn kommuniziert wird. (Es wird ja nicht für jeden Thread ein neues Netzwerkkable an den Computer gesteckt :wink: ). Aber von Netzwerkzeug habe ich zu wenig Ahnung, als dass ich sagen könnte, WO es da genau zu Problemen kommen kann....
 
Mit einer derartigen Monitorverteilung provozierst du höchstens Deadlocks. Dein Vorhaben ist kaum mit geringem Aufwand machbar.

Schreib dir eine Batch, das die einzelnen Programme in unterschiedlichen VMs startet und fertig.

mpG
Tobias
 
Habs gelöst:

man ruft das ganze mit:
Code:
for (int i = 1; i < 9; i++) {
            Thread t2 = new Thread(new Init());
            new Thread(t2).start();
        }

und schon hat man 8 unabh. Threads bzw. Programme. Gracias!
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben