Java синхронизированная функция разблокировки при обратном вызове - PullRequest
0 голосов
/ 17 января 2020

У меня есть класс с функцией GetTemperature(), который:

  1. Подключается к устройству
  2. Отправляет команду устройству для считывания температуры
  3. Обратный вызов OnGetTemperature() запускается при считывании температуры
  4. При обратном вызове я отключаюсь от устройства

Эта функция вызывается из приложения React Native в Android и можно вызывать несколько раз. У меня нет доступа к приложению React Native для ограничения вызовов функций. Проблема в том, что я хочу сделать эту функцию синхронной. Потому что только одно соединение может быть активным одновременно.

Я пытался сделать функцию GetTemperature() синхронной, но эта функция возвращается рано и не ожидает OnGetTemperature(), так что это не сработало. Есть ли способ заблокировать функцию и разблокировать ее от обратного вызова? Я попытался ReentrantLock, чтобы заблокировать класс при вызове GetTemperature() и разблокировать его в обратном вызове. Но при срабатывании обратного вызова приложение вылетает. Может быть, объект заблокирован и обратный вызов не может быть запущен из другого потока?

1 Ответ

0 голосов
/ 17 января 2020

Semaphone сделает то, что вам нужно:

public class Test {

private Semaphore semaphore = new Semaphore(1); // Allow max 1 'palyer'

public static void main(String[] args) {
    Test t = new Test();
    t.start(1);
    t.start(2);
    t.start(3);
    t.start(4);
}

private void start(int i) {
    try {
        semaphore.acquire();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("start " + i);
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            stop(i);
        }
    };
    new Thread(runnable).start();
}

private void stop(int i) {
    System.out.println("stop " + i);
    semaphore.release();
}
}

При первом вызове start acqu увеличится счет semaphore's, а затем продолжится (печать «старт 1» и т. Д.). Во второй раз, когда вы вызываете start, выполнение будет продолжаться до тех пор, пока не будет вызван release, что произойдет, когда поток «start 1» вызовет stop через 100 мс.

Выход будет start 1, stop 1, start 2, stop 2, ... что вы хотите. Если вы удалите семафор, результат будет start 1, start 2, start 3, start 4, stop 1, stop 2, stop 3, stop 4, что вам нужно.

В вашем случае это обратный вызов, который вызывает stop, а не поток, но я уверен, что вы все еще видите, что Я имею в виду.

Чтобы ваше решение было завершено, вам нужно добавить некоторую обработку ошибок. Например, вы не можете быть уверены, что всегда будут обратные вызовы. Так что вы, вероятно, хотите позвонить. release из start, если stop ждал обратного вызова, например, 10 секунд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...