如何使用 AtomicBoolean 进行阻塞和等待

发布于 2024-12-17 06:27:42 字数 923 浏览 0 评论 0原文

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

我首先有效地使用布尔标志(称为“暂停”),并用 while 循环包装检查(暂停)。

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

我一直在研究 AtomicBoolean,它似乎可以解决问题,除了它不会阻塞。

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

即类似于 AtomicBoolean.getFalse()AtomicBoolean.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();
        }
    } 
}

I am looking for a way of pausing a Thread.

I started with affectively using a boolean flag (called 'paused'), and wrapping a check with a while loop (pause).

Within the while loop there’s a Thread.wait() to block the execution.

I’ve been looking at the AtomicBoolean, which seems to do the trick apart from it doesn’t block.

Is there a alternative or extended version of AtomicBoolean that has a block method ?

i.e. something like AtomicBoolean.getFalse() of AtomoicBoolean.get(false)?

They have a Blocking Queue, so a Blocking value.

Current setup is :

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

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

            paused.notify();
        }
    }

with

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

}


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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆梦 2024-12-24 06:27:42

使用 CountDownLatch 为 1:

CountDownLatch conditionLatch = new CountDownLatch(1);

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

conditionLatch.await();

在您想要将条件设置为 true 的地方:

conditionLatch.countDown();

Use a CountDownLatch of 1:

CountDownLatch conditionLatch = new CountDownLatch(1);

In the place you want to wait for some condition to become true:

conditionLatch.await();

In the place you want to set the condition to true:

conditionLatch.countDown();
小巷里的女流氓 2024-12-24 06:27:42
    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
        }
    }       
}   

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

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

First, unless you use an atomic operation (something like test-and-set), AtomicBoolean is as useless as a regular Boolean (If they were mutable). Here I'm using compareAndSet, so that it only enters the critical section if the flag was down. Remember to always unlock in finally.

To pause a thread using a flag, don't go for active wait (some loop in thread body asking "Am I paused?"), as it is not an efficient practice. I'd use a wait-notify scheme. When the thread has no more work to do, it calls wait on some object. Then, to restart, some other thread calls notify on that same object.

If you want to immediately pause (in terms of skip execution when the flag is set), you could divide the code in as much steps as possible, and wrap each one with a test, to finally wait if paused:

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

Depending of your code, the steps may be even nested, or include undivisible units of execution involving several steps.

素染倾城色 2024-12-24 06:27:42

我不确定我是否理解了你的问题;你看过java.util.concurrent.Semaphore类吗?
具有 permits=1Semaphore 应该为您提供所需的行为,

paused=true;

模拟您的指令

semaphore.tryAcquire();

,您可以使用或 来

semaphore.acquire();

如果您想锁定调用者 。
您可以使用以下命令释放线程

semaphore.release();

I'm not sure I did understand your question; did you look at the class java.util.concurrent.Semaphore?
A Semaphore with permits=1 should give you the desired behaviour, you can emulate your

paused=true;

instruction with

semaphore.tryAcquire();

or

semaphore.acquire();

if you want to lock the caller.
You can release the thread with

semaphore.release();
紫南 2024-12-24 06:27:42

您可以使用锁。

在你的线程中。

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

You can use a lock.

In your thread.

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.

Or you could busy sleep depending on how quickly you need a thread to wake up.

while(atomicBoolean.get()) Thread.sleep(100); // or yield();
桃扇骨 2024-12-24 06:27:42

您要么正在等待特定时间,这可以通过 Thread.sleep() 来完成,要么您需要等待某些东西,这表明您需要调用wait() 在您等待准备就绪的对象上。

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

Either you are waiting for a specific time, which can be done with Thread.sleep() or you need to wait for something, which would indicate, that you need to call wait() on the object you are waiting for to be ready.

If you really need to be manually able to tell your thread to continue working, build a while(true) loop containing a Thread.sleep() call and a check for a boolean which leads to a break if properly set. I can't really think of a reason to do that though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文