2013-12-15 51 views
1

我做了这个样本,以了解如何等待通知的作品:等待通知由同一个对象同步不起作用

public class WaitingTest implements Runnable { 

    Thread b = new Thread(); 
    int total; 

    public static void main(String[] args){ 
     WaitingTest w = new WaitingTest(); 
    } 

    public WaitingTest(){ 
     b.start(); 
      synchronized(b){ 
       try{ 
        System.out.println("Waiting for b to complete..."); 
        b.wait(); 
       }catch(InterruptedException e){ 
        e.printStackTrace(); 
       } 
       System.out.println("Total is: " + total); 
      } 
    } 

    @Override 
    public void run(){ 
     synchronized(b){ 
      for(int i=0; i<100 ; i++){ 
       total += i; 
       System.out.println(total); 
      } 
      b.notify(); 
     } 
    } 
} 

但我困在这里小时,我不明白为什么它的不太工作。我的输出应该超过0,但它总是零...我想知道是否它的使用不同的线程,但林不知道真的..我错过了什么?

+0

尝试启动线程=) –

+0

你能告诉我们你认为你的'run'方法应该在哪里执行吗? – Pshemo

回答

4

我认为你的理解存在一些严重漏洞。你已经宣布Thread

Thread b = new Thread(); 

,并在构造函数中启动它

b.start(); 

Thread将启动并死马上,因为它没有Runnable连接到它。

碰巧的是,当一个Thread死了,它本身调用notify()因为你是​​同Thread对象上,你wait()荷兰国际集团线程将被唤醒。你也在这里参加比赛。如果Thread在主线程到达wait()之前结束,您将会死锁。

而且,没有理由run()被调用,这就是为什么total保持为0


任何对象可以是​​上,它并没有成为一个Thread。而且由于Thread有自己的奇怪行为,所以你可能不应该使用它。

您应该通过Threadtutorialssynchronization tutorials

+0

运行附件来自''线程b =新线程(this);''然后 - 我会看看教程,thx –

+0

@Victor欢迎您。是的,您必须将'this'实例(或另一个'Runnable')传递给'Thread'构造函数才能使用它。 –

1

除了与你是如何安排你的线程的问题,你有一个不正确使用wait()/通知()

通知()是无状态的。如果没有线程在等待,则不会通知任何内容。如果稍后等待(),它将不会被通知。

wait()可以虚假地唤醒。仅仅因为wait()醒来并不意味着任何通知它。

这意味着你需要等待关联/与状态通知(实际上它是相当没有意义,没有它)

例如。

// to notify 
synchronized(lock) { 
    signalled = true; 
    lock.notify(); 
} 

// to wait 
synchronized(lock) { 
    while(!signalled) 
      lock.wait(); 
} 
+0

我也在想这个,如果我在同步之后调用''b.notify();'',那么total的值应该是0,但不知何故它不是。 –