【问题标题】:How to Block and wait using AtomicBoolean如何使用 AtomicBoolean 阻塞和等待
【发布时间】:2012-01-03 00:39:22
【问题描述】:

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

我从有效地使用布尔标志(称为“暂停”)开始,并使用 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();
        }
    } 
}

【问题讨论】:

    标签: java concurrency atomic java.util.concurrent


    【解决方案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();
    

    【讨论】:

    • 我认为是一个锁,并且只能从同一个线程解锁,如果线程 1 调用了锁,我不相信线程 2 可以调用解锁。
    • 是的,这就是我添加评论的原因。 ;) 恕我直言,如果不同的线程可以启动/停止这个线程,这似乎有点随机。
    • 是的,它是一个 Web 应用程序向正在运行的线程发送请求,以使其暂停。我只是在寻找一种单行的方式,而不是使用 wait() 和 notify() 同步块。
    【解决方案2】:

    要么你在等待一个特定的时间,这可以用Thread.sleep()来完成,要么你需要等待for某事,这表明你需要在对象上调用wait()你正在等待准备好。

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

    【讨论】:

    • 我已经使用了一个普通的布尔值和一个同步方法,比如 synchronized (this) { while (paused) { try { wait(); } 捕捉(异常 e){ } } this.notify(); } 但正在寻找一种包罗万象的方法。
    • 嗯...我的意思是你很可能以错误的方式思考你的问题。
    • 其原因,归结为暂停执行。我目前有 wait() 方法。所以你有一个线程,你想暂停或停止继续,一个标志被放置,此刻我有一个如果为真,等待监视器。我希望阻止实际状态。
    【解决方案3】:

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

    暂停=真;

    使用说明

    semaphore.tryAcquire();

    信号量.acquire();

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

    释放线程

    semaphore.release();

    【讨论】:

    • 我会看看这个,并对其进行测试,但我认为发布只能由获得许可的线程完成。因此线程 1 不能释放线程 2 获得的许可。我想我可能不得不坚持 Thread.wait()
    • javadoc 说:没有要求释放许可的线程必须通过调用acquire() 获得该许可。信号量的正确使用由应用程序中的编程约定确定。
    • 信号量的静态实例完成这项工作
    【解决方案4】:
        AtomicBoolean lock = new AtomicBoolean(false);
        if(lock.compareAndSet(false, true)){
            try {
                //do something
            } catch(Exception e){
                //error handling
            } finally {
                lock.set(false);
            }
        }
    

    首先,除非您使用原子操作(例如测试和设置),否则AtomicBoolean 与常规布尔值一样无用(如果它们是可变的)。这里我使用compareAndSet,因此只有在标志关闭时它才会进入临界区。请记住始终在 finally 中解锁。

    要使用标志暂停线程,不要进行主动等待(线程主体中的一些循环询问“我暂停了吗?”),因为这不是一种有效的做法。我会使用等待通知方案。当线程没有更多工作要做时,它会在某个对象上调用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
            }
        }       
    }   
    

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

    【讨论】:

    • 谢谢,这(带有等待通知方法的布尔值)几乎是我已经做过的,但希望在并发包中已经为我做了一些事情。
    【解决方案5】:

    使用 1 的 CountDownLatch

    CountDownLatch conditionLatch = new CountDownLatch(1);
    

    在你想等待某个条件成立的地方:

    conditionLatch.await();
    

    在你要设置条件为真的地方:

    conditionLatch.countDown();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多