首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CountDownLatch同步

CountDownLatch同步
EN

Stack Overflow用户
提问于 2012-03-24 04:48:29
回答 3查看 2.3K关注 0票数 1

我有一个getNewA()方法,它应该在其他线程调用setA(x)之前阻塞。使用CountDownLatch是否正确?我注意到有一个数据竞争,在gate.await()解锁之后,另一个线程可能会使用旧的闩锁调用setA(x),因此可能会遗漏一个值。我考虑过同步getNewA(),但这不会导致死锁吗?对于如何处理这个问题,有什么建议吗?

代码语言:javascript
复制
package test;

import java.util.concurrent.CountDownLatch;

public class A {

    private int a;
    private CountDownLatch gate;

    public A(int a) {
        a = 1;
        gate = new CountDownLatch(1);
    }

    A getNewA() throws InterruptedException {  // wait for new a...
        gate.await();

        gate = new CountDownLatch(1);
        return this;
    }

    public synchronized int getA() {
        return a;
    }

    public synchronized void setA(int a) {      
        gate.countDown();
        this.a = a;
    }
}
EN

回答 3

Stack Overflow用户

发布于 2012-03-24 05:07:01

使用Phaser。你可以像你想要的那样在这里重用它,而不需要创建一个新的屏障实例。

代码语言:javascript
复制
public class A {

    private int a
    private final Phaser phaser = new Phaser(1);


    public A(int a) {
        a = 1;
    }


    A getNewA() throws InterruptedException {  // wait for new a...
        phaser.awaitAdvance(phaser.getPhase());
        return this;
    }

    public synchronized  int getA() {
        return percent;
    }

    public synchronized void setA(int a) {      
        this.a = a
        phaser.arrive();
    }
}

每次调用setA时,它将递增到一个新的阶段,并且phaser.awaitAdvance(phaser.getPhase())将返回。此时,新阶段将等于phaser.getPhase()+1

注意:这需要Java7。

票数 2
EN

Stack Overflow用户

发布于 2012-03-24 06:17:21

另一种方法是自己处理同步。我认为您需要的是让getA返回一个值,该值是在线程当前进入之后设置的。您可以将其用作wait()标准。

代码语言:javascript
复制
public class A {

    private int a;
    private long updateCount = 0;

    private final Object lock = new Object();

    public A getNewA() throws InterruptedException {  // wait for new a...
        synchronized(lock) {
           long currentCount = updateCount ;
           while (currentCount == updateCont) {//assumes never decrementing
              lock.wait();
           }
           return this;
        }
    }

    public int getA() {
        synchronized(lock) {
             return a;
        }
    }

    public void setA(int a) {      
        synchronized(lock) {
             this.a = a;
             updateCount++;
             lock.notifyAll();
        }
    }
}

编辑:正如TomAnderson提到的,竞争条件是可能的。谢谢

票数 1
EN

Stack Overflow用户

发布于 2012-03-24 05:53:38

您可以使用Semahore

代码语言:javascript
复制
package test;

import java.util.concurrent.Semaphore;

public class A {

    private int a
    private Semaphore semaphore = new Semaphore(0);


    public A(int a) {
        a = 1;            
    }


    A getNewA() throws InterruptedException {  // wait for new a...
        semaphore.acquire();
        return this;
    }

    public synchronized int getA() {
        return percent;
    }

    public synchronized void setA(int a) {                  
        this.a = a;
        semaphore.release();
    }
}

如果信号量只剩下0个许可,并且两个线程相继调用getA,则这两个线程都将阻塞,并且在调用setA时,不确定地选择其中只有一个线程被唤醒。

如果setA在一个序列中被调用两次,它将允许两个线程下次调用getA,这可能不是您想要的,因为这两个线程都将获得对this的相同引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9846307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档