简体   繁体   English

在多个线程之间同步数据

[英]Synchronize data between many threads

I'm new to the synchronization topic and I couldn't find clear information anywhere about using wait() , notify() , and notifyAll() methods while trying to access to synchronized object. 我是同步主题的新手,在尝试访问同步对象时,我找不到任何有关使用wait()notify()notifyAll()方法的明确信息。 For exmaple if we have such code: 例如,如果我们有这样的代码:

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

Should we call wait() in methodY() and notify() at the end of methodX() ? 我们应该调用wait()methodY()notify()在结束methodX() Otherwise we will not assign any value to z or the thread will wait without explicitly calling wait() until X unlocks? 否则,我们将不会为z分配任何值,否则线程将在不显式调用wait()情况下wait()直到X解锁为止。

So give that you need methodY to wait until methodX has executed, one valid way of doing this is wait and notify or notifyAll . 因此,假设您需要methodY等到methodX执行methodX ,一种有效的方法是waitnotifynotifyAll There are of course multiple other ways but that one is valid. 当然,还有其他多种方法,但其中一种是有效的。 Given that you may not even need the synchronized block. 鉴于您甚至可能不需要同步块。

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

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

You might consider putting the blocking code in a getX method in X but the above will work IF (and this is a BIG IF) you can guarantee that methodY starts before methodX because otherwise methodY will miss the notify call. 您可能考虑将阻塞代码放入XgetX方法中,但是上述方法在IF起作用(并且这是BIG IF)时,您可以保证methodYmethodX之前启动,因为否则, methodY将丢失notify调用。

All of the above said, I agree with JB Nizet , you might consider a more high-level mechanism such as a Semaphore / Mutex / etc. These ease the complexity. 综上所述,我同意JB Nizet ,您可以考虑使用更高级的机制,例如Semaphore / Mutex /等。这些机制可以简化复杂性。 For example if you use a CountDownLatch and create it with a count of 1 your code will probably be more robust... 例如,如果您使用CountDownLatch并以1计数创建它,则您的代码可能会更健壮...

Consider: 考虑:

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

The above will work every time without any ordering risks. 以上内容将每次都有效,没有任何订购风险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM