2017-05-23 120 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; 
     } 
    } 

} 
相关问题