2013-10-15 5 views
2

Я не уверен, что мой подход правильный, поэтому я приложу все усилия, чтобы описать проблему как можно лучше.Ждать, если выполняется определенное условие?

Я программирую клиент, который подключается к серверу. Он часто отправляет некоторый (другой) запрос. Иногда может случиться так, что запросов слишком много, поэтому я вынужден повторно войти в систему. Вход в систему проверяется токеном, установленным в заголовке запроса.

Я хотел бы реализовать что-то вроде объекта блокировки/ожидания. Большинство запросов выполняются в отдельных потоках, но отправляют (окончательный) запрос через одну и ту же функцию. Прямо в этой функции я проверяю ответ на достоверность, и если сервер решил ударить меня, я отправляю запрос на повторный вход.

Моя проблема: если есть недействительный ответ, я повторно подключаюсь асинхронно (обратные вызовы JavaFX для ответа) и продолжаю. В связи с многопоточными задачами может возникнуть условие, при котором два (или более) запроса получают один и тот же недействительный ответ и пытаются повторно войти в систему, или одна задача пытается выполнить запрос, пока другой регистрируется (поэтому нет действительного токена) , получает недействительный ответ, начинает логин, а другой получает действительный логин, который становится недействительным во время нового входа и так далее.

Как я могу заставить свои задачи дождаться завершения запроса, запрошенного другим? Какой был бы лучший подход для этого?

Спасибо и извините за грамматику!

ответ

1

Это, кажется, случай доступа к общему ресурсу. Ваша интуиция с блокировкой/ожиданием верна. Синхронизированный метод кажется хорошим решением для вас. Если это не так, используйте Semaphore.

+0

Спасибо за ответ. Как мне реализовать это ожидание? if (loginFlag) obj.wait(); и в моем loginProcedure loginFlag = true & при успешном входе в систему obj.notifyAll? Я нахожусь на мобильном телефоне, извините за отсутствие форматирования. – Nicolai

+0

Да .. Держите флаг bool - «reLogin», для которого установлено значение false. Если сервер пинает вас, вы должны изменить его на true и уведомить все ожидающие потоки ... Остальные потоки будут ждать этого. – TheLostMind

0

Если у вас есть центральный класс, отвечающие за ваш логин, вы можете использовать Реентрантную замки управлять этим:

private final ReentrantReadWriteLock loginLock = new ReentrantReadWriteLock(); 

public boolean isLoggedIn() { 
    loginLock.readLock().lock(); 
    try { 
     return loggedIn; 
    } 
    finally { 
     loginLock.readLock().unlock(); 
    } 
} 

public void login() { 
    loginLock.writeLock().lock(); 
    try { 
     if (!isLoggedIn()) { 
      performLogin(); 
     } 
    } 
    finally { 
     loginLock.writeLock().unlock(); 
    } 
} 
Смежные вопросы