如何使用AtomicBoolean阻止和等待

时间:2011-11-21 14:09:41

标签: java concurrency atomic java.util.concurrent

我正在寻找一种暂停线程的方式。

我开始使用布尔标志(称为'暂停'),并使用while循环(暂停)包装检查。

在while循环中有一个Thread.wait()来阻止执行。

我一直在关注 AtomicBoolean ,除了它没有阻止外,似乎可以解决这个问题。

是否存在具有块方法的AtomicBoolean的替代版或扩展版?

即。像AtomicBoolean.getFalse() AtomoicBoolean.get(false)之类的东西?

他们有一个阻止队列,所以阻塞值。

目前的设置是:

while (paused.get()) {
        synchronized (paused) {
            try {

                paused.wait();
            } catch (Exception e) {
            }

            paused.notify();
        }
    }

public void pause() {
    if (paused.compareAndSet(false, true)) {
        synchronized (paused) {
            paused.notify();
        }
    }

}


public void resume() {
    if (paused.compareAndSet(true, false)) {
        synchronized (paused) {
            paused.notify();
        }
    } 
}

5 个答案:

答案 0 :(得分:11)

    AtomicBoolean lock = new AtomicBoolean(false);
    if(lock.compareAndSet(false, true)){
        try {
            //do something
        } catch(Exception e){
            //error handling
        } finally {
            lock.set(false);
        }
    }

首先,除非您使用原子操作(类似于测试和设置),AtomicBoolean与常规布尔值一样无用(如果它们是可变的)。在这里我使用compareAndSet,因此只有在标志关闭时它才会进入临界区。记得总是在最后解锁。

要使用标志暂停线程,请不要进行主动等待(线程主体中的某个循环询问“我暂停了吗?”),因为这不是一种有效的做法。我会使用等待通知方案。当线程没有其他工作要做时,它会在某个对象上调用wait。然后,要重新启动,其他一些线程会在同一个对象上调用notify

如果你想立即暂停(就设置标志时的跳过执行而言),你可以在尽可能多的步骤中划分代码,并用测试包装每一个,最后等待暂停:

public void run(){
    while(true){
        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(paused){
            //wait on some object
        }
    }       
}   

根据您的代码,这些步骤可能甚至是嵌套的,或包含涉及多个步骤的不可分割的执行单元。

答案 1 :(得分:4)

使用CountDownLatch 1:

CountDownLatch conditionLatch = new CountDownLatch(1);

在你想等待某种情况成真的地方:

conditionLatch.await();

在您要将条件设置为true的位置:

conditionLatch.countDown();

答案 2 :(得分:2)

我不确定我是否理解了你的问题;无论如何你看过java.util.concurrent.Semaphore类吗? permit = 1的信号量应该给你想要的行为,你可以模仿你的

暂停= TRUE;

指令

semaphore.tryAcquire();

semaphore.acquire();

如果你想锁定来电者。 您可以使用

释放该帖子

semaphore.release();

答案 3 :(得分:1)

你可以使用锁。

在你的主题中。

while(!Thread.interrupted()) {
  lock.lock();
  try {
      // do something.
  } finally {
      lock.unlock();
  }
}

// to pause
lock.lock();

// to unpause
lock.unlock(); // has to be the same thread which locked.

或者你可以忙着睡觉,这取决于你需要一个线程唤醒的速度。

while(atomicBoolean.get()) Thread.sleep(100); // or yield();

答案 4 :(得分:0)

您要么等待特定时间,可以使用Thread.sleep()来完成,或者您需要等待 某些事情,这表明您需要致电{{1}在你正在等待准备好的对象上。

如果您真的需要手动告诉您的线程继续工作,请构建一个包含wait()调用的while(true)循环,并检查导致Thread.sleep()的布尔值如果设置得当。我不能想到这样做的理由。