如何使用原子布尔值阻止和等待

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

我从情感地使用布尔标志(称为“暂停”)开始,然后用一段时间循环(暂停)包装支票。

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

答案 1

使用 a 的 1:CountDownLatch

CountDownLatch conditionLatch = new CountDownLatch(1);

在您想要等待某些条件变为真的地方:

conditionLatch.await();

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

conditionLatch.countDown();

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

首先,除非你使用原子操作(类似于test-and-set),否则它与常规布尔值一样无用(如果它们是可变的)。在这里,我使用的是 ,因此仅当标志关闭时,它才会进入关键部分。请记住,最后总是解锁。AtomicBooleancompareAndSet

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

如果要立即暂停(在设置标志时跳过执行),则可以将代码分成尽可能多的步骤,并用测试包装每个步骤,以便在暂停时最后等待:

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

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


推荐