Как заставить поток ждать отработки слушателя внутри другого класса через wait/notify?
Всем привет. Задача такая: запускаю поток, который в свою очередь подключается к серверу, вытаскивает нужную информацию, компилирует в файл и файл отправляет на другой сервер, затем поток ждет около часа и повторяет операцию. При запуске потока создаю цикл
public void run() {
while (!isInterrupted()){
adapter = new ConnectAdapter(this);
synchronized (adapter) {
adapter.connect();
try {
adapter.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Затем внутри класса ConnectAdapter происходит вся логика которая собирает инфу и отправляет файл на сервер и в конце вызывает метод notyf. Но основной поток не продолжает свою работу, то есть что бы я не написал после строчки adapter.wait() не выполнится. А задумка в том, что после этого поток запишет время выполнения и уйдет спать на час, а затем все заново. Не могу сообразить как сделать правильное ожидание.
Ответы (1 шт):
У вас adapter.connect(); без блокировки? Если с блокировкой, то notify() в нем вызывается раньше чем вы вызываете wait(). Как следствие монитор не сбрасывается и ждет.
Можно использовать шудлер для решения:
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(new MyThread(), 0, 1, TimeUnit.HOURS);
Поток будет создаваться и выполняться каждый час. Собственно метод должен теперь выглядеть так:
public void run() {
adapter = new ConnectAdapter(this);
adapter.connect();
}
Если вы хотите оставить свой вариант то можно использовать Semaphore. Даже если adapter.connect(); с блокировкой, то ваш код будет выполнять так, как вы этого ожидаете.
class MyThread extends Thread {
private final Semaphore semaphore;
MyThread() {
this.semaphore = new Semaphore(1);
}
@Override
public void run() {
var adapter = new ConnectAdapter(semaphore);
try {
adapter.connect();
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
В ConnectAdapter
public void connect() {
...
...
...
semaphore.release();
}