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

wait()我们应该在结束时methodY()调用吗?否则我们不会分配任何值,或者线程将等待而不显式调用,直到 X 解锁?notify()methodX()zwait()

4

1 回答 1

2

因此,如果您需要methodY等到methodX执行完毕,一种有效的方法是waitand notifyor notifyAll。当然还有其他多种方式,但那一种是有效的。鉴于您甚至可能不需要同步块。

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

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

您可能会考虑将阻塞代码放在一个getX方法中,X但如果上面的方法可以工作(这是一个 BIG IF),您可以保证methodY之前开始,methodX否则methodY会错过notify调用。

综上所述,我同意JB Nizet,您可以考虑使用更高级的机制,例如 Semaphore / Mutex / 等。这些减轻了复杂性。例如,如果您使用 aCountDownLatch并使用计数 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();
    }
}

以上将每次都有效,没有任何订购风险。

于 2013-05-08T12:32:11.277 回答