Ждите и оповестите о той же теме - PullRequest
0 голосов
/ 12 декабря 2018

Есть ли один единственный поток, который может подождать и уведомить себя, чтобы он "проснулся", или только

Я получил что-то вроде этого, но это не работает, и я получил незаконное наблюдение мониторов

public class test extends Thread{


private int n;
private int lim;

public test(int lim) {
    n = 0;
    this.lim=lim;
}

public synchronized void add() throws InterruptedException {
    n++;
    notify();
}


@Override
public void run() {

    while(n!=lim){
        try {
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //do something
}

}

Main

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Путаница здесь, похоже, связана с идеей "уведомления потока".Вы (обычно) не вызываете notify, notifyAll или wait объекта Thread.Вызовите любой объект, который вы используете в качестве блокировки.(Особая проблема с Thread заключается в том, что он уже используется в качестве блокировки для определенной цели (Thread.join).)

Так что вам нужен какой-то объект блокировки:

private final Object lock = new Object();

Чтобы подождать на объекте, вам нужно удерживать блокировку, и условие должно проверяться в цикле while.

    synchronized (lock) {
        while (!some_condition) {
            lock.wait();
        }
        ...
    }

Чтобы уведомить, удерживайте блокировку, сообщите (вы также можете пойтидля notifyAll это будет по крайней мере так же хорошо, как notify, а иногда это может быть необходимо, но не попадется на тестирование) и изменит условие.

    synchronized (lock) {
        lock.notifyAll();
        some_condition = true;
    }

Кроме того, хорошей практикой является неподкласс Thread.Идет и для других ненужных подклассов тоже.Обычно вы создаете Runnable и передаете его конструктору.

0 голосов
/ 12 декабря 2018

IllegalMonitorStateException означает, что вы «не владеете монитором».Для этого:

synchronized (this) {
    wait()
}

Что вы хотите, чтобы вызвать уведомление?Как указано выше, если поток ожидает, он не может предпринимать никаких действий.Может быть, вы хотите использовать тайм-аут?

Обновление:

До wait() до достижения lim, добавьте это к методу add():

if (n >= lim) {
    notify();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...