我正在寻找一种暂停线程的方法。
我首先有效地使用布尔标志(称为“暂停”),并用 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();
}
}
}
使用
CountDownLatch
为 1:
CountDownLatch conditionLatch = new CountDownLatch(1);
在你想要等待某个条件成立的地方:
conditionLatch.await();
在你想要将条件设置为true的地方:
conditionLatch.countDown();
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
}
}
}
根据您的代码,这些步骤甚至可能是嵌套的,或者包含涉及多个步骤的不可分割的执行单元。
我不确定我是否理解了你的问题;你看过班级吗
java.util.concurrent.Semaphore
?
带有 Semaphore
的 permits=1
应该会给你所需的行为,你可以模仿你的
paused=true;
使用说明
semaphore.tryAcquire();
或
semaphore.acquire();
如果您想锁定来电者。 您可以使用
释放线程semaphore.release();
您可以使用锁。
在你的帖子中。
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();
您正在等待特定时间,这可以通过
Thread.sleep()
完成,或者您需要等待 for 某件事,这表明您需要对正在等待准备就绪的对象调用 wait()
.
如果您确实需要手动告诉线程继续工作,请构建一个
while(true)
循环,其中包含 Thread.sleep()
调用并检查布尔值,如果设置正确,该布尔值会导致 break
。但我真的想不出这样做的理由。