У меня есть Thread, и мне нужно установить, когда он прослушивает или находится в режиме ожидания, поскольку я определил
public static enum ListenerState { STAND_BY, LISTENING };
и метод
public void setState(ListenerState state){
this.state = state;
}
теперь, в основном цикле, я проверяю состояние таким образом
@Override
public void run() {
while (!Thread.interrupted()) {
try {
if (state==ListenerState.LISTENING){
// do my job
}
else{
Thread.sleep(300);
}
}
}
}
Является ли этот подход безопасным для потоков?
Нет, сделайте так:
class MyThread implements Runnable {
private volatile ListenerState state;
public synchronized void setState(ListenerState state){
this.state = state;
}
@Override
public void run() {
while (true) {
try {
if (state==ListenerState.LISTENING){
// do my job
} else{
Thread.sleep(300);
}
} catch (IterruptedException ex){
return;
}
}
}
}
Вы можете найти свой ответ здесь: нужно ли добавить некоторые блокировки или синхронизацию, если есть только одна запись потока и чтение нескольких потоков?
одним словом: лучше добавить ключевое слово volatile
в состояние.
если состояние может быть изменено или прочитано другим потоком, тогда вам нужно синхронизировать блок для чтения и записи. или как лучший способ, используйте AtomicBoolean
. это идеальный объект, чтобы избавиться от блока syncronize и сделать его потокобезопасным
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html