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), 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
}
}
}
В зависимости от вашего кода шаги могут быть даже вложенными или включать неделимые единицы выполнения, включающие несколько шагов.