2017-05-23 118 views
0

我有2個線程T1和T2。 T2從T1收到消息後應該開始工作。 T1和T2都在main()中啓動。 T1不能啓動T2。如何確保線程在另一個線程之前啓動?

這是我到目前爲止有:

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

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

的問題是,有時T1 T2是之前啓動和T2從來沒有得到的,通知T1發送並永遠等待。

我可以使用任何現有的併發實用程序來實現此信令嗎?

謝謝。

回答

1

一般而言,無論何時使用wait()notify(),都應該有某種機制(例如標記變量)來檢查是否已完成等待。從the Javadoc for wait()

[…]此方法應始終在循環中使用:

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

在你的情況,這意味着,你如果不這樣做其實根本不會進入循環需要等待。

也就是說,您可能想重新考慮從main()啓動這兩個線程;從你的描述來看,爲什麼你這樣做並不明顯。

0

你應該讓T1等待,而t2沒有發送消息。
添加一個共享變量來表示消息,並在while語句中使用它。
lock2.send(); invoke lock2.notify();在T2中,以便在T1等待時通知T1。

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

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

您需要兩個線程之間的一些同步機制。以下是我爲此使用CountDownLatch的一個示例。我定義了一個SyncedThread類,它在構造函數中傳入一個CountDownLatch

在主要方法中,我創建了這個類的兩個實例。首先,thread1將運行2秒鐘,然後發出CountDownLatch信號,然後再進行一次虛擬睡眠3秒。 第二個實例thread2將等待CountDownLatch,然後將休眠5秒模擬工作。

thread2.start()方法首先被調用,然後用thread1.start() 500毫秒的延遲,但通過使用synchronisatio你會在實際thread2等待thread1輸出中看到。

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; 
     } 
    } 

} 
相關問題