2016-07-27 36 views
0

我有两个线程t0和t1,分别在代码段Run_0和Run1中列出了runnables。我想要做的是,当t0正在写或执行持续7秒的任务时,t1应该在等待。当经过7秒时,应该通知t1继续工作。我尝试使用wait()和notify(),但在运行时我期望t0启动,但控制台只显示“T1正在工作”,t0不打印任何东西,就好像它不是 开始wait()不强制线程等待?

请让我知道为什么会发生这种行为。

代码

public static void main(String[] args) { 

    t0 = new Thread(new Run_0()); 
    t1 = new Thread(new Run_1()); 

    t0.start(); 
    t1.start(); 
} 

private static class Run_0 implements Runnable { 

    public void run() { 
     // TODO Auto-generated method stub 

     while (true) { 
      long startTime = TimeUtils.getTSSec(); 
      synchronized (t1) { 
       try { 
        t1.wait(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 

      System.out.println("T0 is writing"); 
      //simulate doing some work 
      while((TimeUtils.getTSSec()-startTime) <= 7) { 

      } 
      System.out.println("T0 finished writing"); 

      synchronized (t1) { 
       t1.notify(); 
      } 

      startTime = TimeUtils.getTSSec(); 

      while((TimeUtils.getTSSec()-startTime) <= 7) { 

      } 
     } 

    } 

} 

private static class Run_1 implements Runnable { 

    public void run() { 
     // TODO Auto-generated method stub 

     while(true) { 

      System.out.println("T1 is working"); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

} 
+0

也许你应该先看看如何在这里首先使用'wait'和'notify':http://www.qat.com/using-waitnotify-instead-thread-sleep-java/ – nidomiro

+0

或者在这里,https ://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html –

回答

0

waitnotifynotifyAll应内部​​块。你有一个notify是外面:

 t1.notify(); // <------- 
     startTime = TimeUtils.getTSSec(); 
+0

好吧,我纠正了代码,现在t1.notify在同步块内,但我仍然得到相同的结果 – user2121

+0

虽然你的声明是正确的,它没有解决这个问题。 – bradimus

+0

@bradimus编辑之前的问题引用了正在发生的异常,现在它被删除,不知道为什么(http://stackoverflow.com/posts/38612670/revisions)。 –

1

javadocs(重点煤矿):

导致当前线程等待,直到其他线程调用notify()方法或为notifyAll()方法这个对象。

您的代码导致t0等待,而不是t1。只有

0

控制台显示“T1工作”和T0打印什么,如果它没有启动

正确的,因为在Run_0.run()的第一件事就是t1.wait();。等待有人拨打t1.notify()t1.notifyAll()。我看到没有人叫这些。

当线程在对象上调用wait()时,它会导致线程等待通知对象的监视器。一个线程不会导致另一个线程等待。它只能等待自己。

意识到您正在同步,等待并通知发生线程的对象t1是很重要的。两个线程之间共享的任何对象将工作,因为我们正在与锁定t0t1线程对象的困惑,你应该建立最终锁定对象并锁定它:

private final Object lock = new Object(); 

T0是写或者执行持续7秒的任务,t1应该等待。

所以这听起来像你应该在Run_1类不是Run_0t1.wait()。也许Run_0应该做的:

// much better way to simulate time passing instead of a spin loop 
Thread.sleep(7000); 
System.out.println("T0 finished writing"); 
synchronized (lock) { 
    lock.notify(); 
} 

,然后在Run_1你会做这样的事情:

synchronized (lock) { 
    lock.wait(); 
} 
System.out.println("T1 is working"); 

请注意,我使用的是常见的lock对象。

+0

我认为RUN_1应包含:同步(T0){ \t \t \t \t \t \t尝试{ \t \t \t \t \t \t \t t0.wait(); \t \t \t \t \t \t} – user2121

+0

无论您user @ user2121是什么对象。你只需要在两个线程中使用相同的对象。我会改变我的答案。 – Gray

+0

我更新了我的answer @ user2121,它试图解释使用线程对象会让您对object.wait()和object.notify()的理解混淆。希望能帮助到你。 – Gray