17

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

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

5 回答 5

15

使用CountDownLatch1:

CountDownLatch conditionLatch = new CountDownLatch(1);

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

conditionLatch.await();

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

conditionLatch.countDown();
于 2018-03-27T23:11:59.947 回答
14
    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
        }
    }       
}   

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

于 2011-11-21T16:02:09.360 回答
3

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

暂停=真;

指令与

信号量.tryAcquire();

或者

信号量.acquire();

如果你想锁定来电者。你可以释放线程

信号量.release();

于 2011-11-21T14:41:55.043 回答
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();
于 2011-11-21T14:13:51.143 回答
0

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

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

于 2011-11-21T14:14:03.170 回答