2013-05-08 62 views
1

我是新同步主题,在尝试访问同步对象时找不到有关使用wait(),notify()notifyAll()方法的任何地方的明确信息。对于〔实施例,如果我们有这样的代码:同步多个线程之间的数据

class X extends Thread { 
    int x; 

    public void methodX() 
    { 
     synchronized(this) 
     { 
      //some operations on x 
     } 
    } 
} 

class Y extends Thread { 
    public void methodY(X x) 
    { 
     int z = x.x; 
    } 
} 

我们应该倡导:在methodY()notify()wait()methodX()结束了吗? 否则,我们不会为z分配任何值,否则线程将等待,直到X解锁为止,而不显式调用wait()

+0

你想做什么?包括主要() – 2013-05-08 12:24:20

+2

不,你不应该。由于X.x被多个线程访问,所以每个访问都应该简单地在同一个对象上同步。阅读Brian Goetz的[Java并发教程](http://docs.oracle.com/javase/tutorial/essential/concurrency/)和Java Concurrency in Practice。还请阅读wait()和notify()的javadoc以了解它们的用途和用途。 – 2013-05-08 12:25:49

+0

请澄清一下......你的要求是'method'的赋值在'methodX'执行之后才会出现? – 2013-05-08 12:27:15

回答

2

所以给你需要methodY等到methodX已执行,这样做的一个有效方法是waitnotifynotifyAll。当然还有其他多种方式,但其中一种是有效的。鉴于你甚至可能不需要同步块。

void methodX(){ 
     // do your work here 
     this.notifyAll(); 
} 

void methodY(X x){ 
    x.wait(); 
    int x = X.x; 
} 

你可能会考虑将阻止代码的getX方法X但上面会工作,如果(这是个很大的可能),你可以methodX之前保证methodY开始,否则methodY将错过notify通话。

以上所有说,我同意JB Nizet,你可能会考虑更高层次的机制,如信号量/互斥/等等。这些减轻了复杂性。例如,如果您使用的是CountDownLatch并用1个代码的计数创建它可能会更强劲...

考虑:

class X{ 
    volatile int x; 
    final CountDownLatch cdl = new CountDownLatch(1); 

    void methodX(){ 
     // do work here 
     cdl.countDown(); 
    } 

    int getX(){ 
     cdl.await(); 
     return x; 
    } 
} 

class Y{ 
    void methodY(X x){ 
     int z = X.getX(); 
    } 
} 

以上将工作每一次,没有任何排序的风险。