2016-03-21 7 views
-1

Ich habe 3 thread, die ich möchte es in der Reihenfolge zu drucken, aber wenn ich das Programm laufen lassen es Ergebnis erhalten. Ich verstehe nicht, wie es Thread in Reihenfolge nicht laufen konnte. Ich möchte Thread 1 und 2 bzw. 3 weiterlaufen lassen. In jedem Thread gibt es eine Schleife zum mehrfachen Drucken. Also würde ich gerne den Haupt-Thread machen, um jeden Thread in Reihenfolge zu durchlaufen. Das ist mein Code.Wie macht man Thread in Ordnung und läuft oft?

threadMessage("Starting MessageLoop thread"); 
long patience = 
long startTime = System.currentTimeMillis(); 
Thread t = new Thread(new MessageLoop()); 
Thread t2 = new Thread(new MessageLoop2()); 
Thread t3 = new Thread(new MessageLoop3()); 
t.setPriority(10); 
t2.setPriority(5); 
t3.setPriority(1); 
t.start(); 
t2.start(); 
t3.start(); 

Das ist mein Thread-Funktion (3 Fäden)

private static class MessageLoop 
    implements Runnable { 
    public void run() { 

     try { 
      for(int i = 0;i<20;i++) 
      {  
       Thread.sleep(1000); 
       // Print a message 
       threadMessage("A"); 
      } 

     } catch (InterruptedException e) { 
      threadMessage("thread interrupted"); 
     } 
    } 
} 
private static class MessageLoop2 
implements Runnable { 
public void run() { 

    try { 
     for(int i = 0;i<20;i++) 
     {  Thread.sleep(1000); 
      // Print a message 
      threadMessage("B"); 
     } 

    } catch (InterruptedException e) { 
     threadMessage("thread interrupted"); 
    } 
} 
private static class MessageLoop3 
implements Runnable { 
public void run() { 
    String importantInfo = "E"; 
    try { 
     for(int i = 0;i<20;i++) 
     {  
      Thread.sleep(1000); 
      // Print a message 
      threadMessage(importantInfo); 
     } 

    } catch (InterruptedException e) { 
     threadMessage("Thread interrupted"); 
    } 
} 

Und dies ist mein Code, um es ausführen, um zu machen. Ich möchte mein Programm in der Reihenfolge wie diese MessageLoop1 und 2 und 3 jeweils ausführen.

 while (t.isAlive()) { 
     threadMessage("Still waiting..."); 

     t.join(2000); 
     if (((System.currentTimeMillis() - startTime) > patience) 
       && t.isAlive()) { 
       threadMessage("Tired of waiting!"); 
       t.interrupt(); 
           // Shouldn't be long now 
       // -- wait indefinitely 
       t.join(); 

      } 
     while(t2.isAlive()){ 
      threadMessage("Still waiting..."); 
      t2.join(1000); 
      if (((System.currentTimeMillis() - startTime) > patience) 
        && t2.isAlive()) { 
        threadMessage("Tired of waiting!"); 
        t2.interrupt(); 
            // Shouldn't be long now 
        // -- wait indefinitely 
        t2.join(); 

       } 
     } 
      while(t3.isAlive()){ 
       threadMessage("Still waiting..."); 
       t3.join(1000); 
       if (((System.currentTimeMillis() - startTime) > patience) 
         && t3.isAlive()) { 
         threadMessage("Tired of waiting!"); 
         t3.interrupt(); 
             // Shouldn't be long now 
         // -- wait indefinitely 
         t3.join(); 

        } 

      } 
     } 

Aber das Ergebnis wie B kommt, A, C. Kann jemand diese Situation erklären? Und ist mein Code falsch? Vielen Dank!

+9

Sie kontrollieren nicht die Reihenfolge; das Betriebssystem tut es. Wenn die Reihenfolge wichtig ist, sollten sie nicht in separaten Threads sein. – duffymo

Antwort

1

So funktionieren Threads. Sie bekommen überhaupt keine Garantie, welcher Thread zuerst fertig wird - und das ist per Design.

Ich nehme an, was Sie wollen, ist eigentlich, was die jdk eine Zukunft und eine ExecutorService nennt.

(Pseudo-Code - werden Syntaxfehler)

ExecutorService s = Executors.newCachedThreadPool(); 
try { 
Future f1 = s.submit(new MessageLoop()); 
Future f2 = s.submit(new MessageLoop2()); 
Future f3 = s.submit(new MessageLoop3()); 
f1.await(10, TimeUnit.SECONDS); // waits for the first thread to finish 
// first thread finished now 
f2.await(10, TimeUnit.SECONDS); 
// second thread finished now 
// ... 

} finally { s.shutdown(); } 

sehr wichtig ist, die richtige Abschalten des ExecutorService zu verwalten, als der Vollstrecker Dienst ein paar Threads verwalten, die, bis Sie sie beenden laufen. Wenn Sie es nicht herunterfahren, wird Ihre Anwendung nicht beendet.

0

Was lässt Sie vermuten, dass Sie die Ordnung kontrollieren?

Die einzelnen MessageLoop-Implementierungen sind in keiner Weise blockiert. So werden sie nur bei der Wahl der Thread-Planung laufen.

Sie müssten eine freigegebene Ressource einführen, die die Rolle der Sperre zwischen dem Steuerelementthread (versucht, die Reihenfolge zu erzwingen) und den Worker-Threads übernimmt.

In Ihrem aktuellen Code wendet der Steuerungs-Thread nur eine spezielle Sequenz an, um die Beendigung der Arbeiter zu erfassen. Das könnte früher ausgeführt und abgeschlossen worden sein.

Wenn Sie an einer sequenziellen Ausführung interessiert sind und die Tasks nicht inline (denselben Thread wie Ihr Steuerelement) ausführen möchten, können Sie die Threads nur sequenziell ausführen, um Ihr Ziel der sequenziellen Ausführung zu erreichen. (Beginnen Sie jeden Thread und warten Sie auf die Beendigung, bevor Sie einen anderen starten).

Da Sie eine Einschränkung in der Reihenfolge der Ausführung haben, benötigen Sie einen Semaphor, um diese Ausführung zu koordinieren.

+0

Wenn Sie die Threads nacheinander gestartet haben, haben Sie immer noch das gleiche Problem;) –

+0

Entschuldigung wegen Unklarheit. Ich wollte ausdrücken, t1 auf Kündigung warten, t2 starten ... und so weiter. – rpy

Verwandte Themen