2017-05-23 2 views
0

Ich habe 2 Threads T1 und T2. T2 sollte seine Arbeit beginnen, nachdem es eine Nachricht von T1 erhalten hat. Sowohl T1 als auch T2 werden in main() gestartet. T1 kann nicht mit T2 beginnen. DieseWie stelle ich sicher, dass ein Thread vor einem anderen Thread gestartet wird?

ist das, was ich bisher:

T1: 
    //do work1 which should be executed before work2 
    lock2.notify() 

T2: 
    lock2.wait(); 
    //do work2 which should be executed after work1 ends 

Das Problem ist, dass manchmal ist T1 gestartet, bevor T2 und T2 wird nie die von T1 gesendet notify und wartet für immer.

Kann ich vorhandene Parallelitätsprogramme verwenden, um diese Signalisierung zu erreichen?

Danke.

Antwort

1

Im Allgemeinen sollten Sie, wann immer Sie wait() und verwenden, auch eine Art von Mechanismus (z. B. eine Markervariable) haben, um zu überprüfen, ob Sie fertig sind. Von the Javadoc for wait():

[& hellip;] Diese Methode sollte immer in einer Schleife verwendet werden:

synchronized (obj) { 
    while (<condition does not hold>) 
     obj.wait(); 
    ... // Perform action appropriate to condition 
} 

In Ihrem Fall bedeutet das, dass man einfach nie die Schleife eingeben, wenn Sie nicht wirklich tun mussen warten.

Das heißt, Sie möchten möglicherweise beide Threads von main() starten; Aus Ihrer Beschreibung ist nicht ersichtlich, warum Sie es so machen.

0

Sie sollten T1 warten, während t2 die Nachricht nicht gesendet hat.
Fügen Sie eine gemeinsame Variable hinzu, um die Nachricht darzustellen, und verwenden Sie sie in einer while-Anweisung.
Und nach lock2.send(); invoke lock2.notify(); `in T2, um T1 zu benachrichtigen, wenn es wartet.

T1: 
    while (lock2.isNotSend()){ 
     lock2.wait(); 
    } 
    lock2.notify() 
    //do some work 

T2: 
    // processing that sends the message 
    lock2.send(); 
    lock2.notify(); 
    lock2.wait(); 
2

Sie benötigen einen Synchronisationsmechanismus zwischen den beiden Threads. Unten ist ein Beispiel, wo ich eine CountDownLatch für diesen Zweck verwende. Ich definierte eine Klasse SyncedThread, die eine CountDownLatch im Konstruktor übergeben bekommt.

In der Hauptmethode erstelle ich dann zwei Instanzen dieser Klasse. Die erste, thread1, wird 2 Sekunden lang ausgeführt, dann wird CountDownLatch signalisiert und dann für weitere 3 Sekunden ein Dummy-Schlaf ausgeführt. Die zweite Instanz thread2 wartet auf den CountDownLatch und wird dann 5 Sekunden lang arbeiten, um Arbeit zu simulieren.

thread2.start() Methode wird zuerst genannt wird, dann ist die thread1.start() mit einer Verzögerung von 500ms, sondern durch die synchronisatio Verwendung finden Sie in der Ausgabe zu sehen, die tatsächlich thread2 für thread1 wartet.

public class ThreadStarterTest { 

    public static void main(String[] args) { 
     final CountDownLatch latch = new CountDownLatch(1); 

     SyncedThread thread1 = new SyncedThread(latch, "thread 1") { 
      @Override 
      public void run() { 
       try { 
        System.out.println(getName() + " running"); 
        Thread.sleep(2_000); 
        latch.countDown(); 
        Thread.sleep(3_000); 
        System.out.println(getName() + " finished"); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 


     SyncedThread thread2 = new SyncedThread(latch, "thread 2") { 
      @Override 
      public void run() { 
       try { 
        latch.await(); 
        System.out.println(getName() + " running"); 
        Thread.sleep(5_000); 
        System.out.println(getName() + " finished"); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 

     try { 
      thread2.start(); 
      Thread.sleep(500); 
      thread1.start(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static class SyncedThread extends Thread { 
     private final CountDownLatch latch; 

     public SyncedThread(final CountDownLatch latch, final String name) { 
      super(name); 
      this.latch = latch; 
     } 
    } 

} 
Verwandte Themen