Использование wait() вызывает IllegalMonitorStateException

212
05 ноября 2018, 14:40
java.lang.IllegalMonitorStateException: object not locked by thread before wait()

Насколько я понимаю, ошибка в том, что или в поток входят объекты, которые не помечены как synchronized или(возможно - и) если такой объект изменится, пока работает wait, то после окончания wait, этот поток может использовать измененный из другого (в моем случае - ui) потока объект. Но кого тогда помечать как synchronized,надо ли это вообще, и почему все работает, если не использовать wait, не понятно. Код:

public class MainActivity extends Activity {
public boolean cycleShouldContinue;
public int counter;
TextView currentCountTextView;
Thread thread;
@Override
public void onCreate (Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView (R.layout.activity_main);
    currentCountTextView = findViewById(R.id.currentCount);
    cycleShouldContinue = true;
    iterationCycle();
}
synchronized public void iterationCycle(){
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (cycleShouldContinue){
                counter++;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        currentCountTextView.setText(String.valueOf(counter));
                    }
                });
                try {
                    thread.wait(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    thread = new Thread(runnable);
    thread.start();
}

Вообще цель - сделать явный экземпляр Thread, чтоб можно было обращаться к нему и вызывать его методы из других мест в программе. (Ведь можно описать новый поток, как будто не выделяя ему имени,но и обратится можно только раз, интересно, как это называется:

new Thread(new Runnable() {
        @Override
        public void run() {
        }
    }).start();

UPD

Вот здесь советуют в первом ответе создавать дополнительно класс-блокировщик какой-то,а как он привязан к моему потоку или нужно наследовать этот клас от Thread или как, вообще ничего не понятно

Answer 1

Надо вызывать метод wait is синхронизированного блока, поскольку у синхронизованного метода используется другой монитор.

synchronized(thread) {
    try {                   
        thread.wait(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }    
}
READ ALSO
Google Drive для хранения данных

Google Drive для хранения данных

Приложение для AndroidНужно запрашивать и сохранять данные (переменные) вне смартфона, чтобы при обновлении приложения данные не терялись

186
Как использовать функцию String.format()?

Как использовать функцию String.format()?

Как можно переписать приведенный код ниже с помощью функции Stringformat()?

196
REST и безопастность

REST и безопастность

Проблема в следующем, юзер-1 генерирует свое проперти и получает свою карточку в профиле с рестом http://site/#/property/17746Юзер-2 перебором (подбором)...

169