Проблема параллелизма для аннулирования цикла опроса

У меня есть проблема, которую, надеюсь, я разрешу, написав этот вопрос, но если нет, я опубликую и посмотрю, поможет ли кто-нибудь.

Я использую клиентскую библиотеку (которая плохо написана мной), чтобы взаимодействовать с чат-сервером реального времени, который использует длительный опрос COMET по HTTP. У меня возникают проблемы с отменой длительного опроса в определенных ситуациях, и я подозреваю, что мне может понадобиться добавить код обработки параллелизма, но мне трудно найти лучший способ сделать это по следующим причинам.

Код подписки (который входит в длинный опрос) реализуется как большой цикл со следующим

doLongPoll() { while(true) } //IF channel field boolean unsubscribe == TRUE, if so BREAK; //perform GET request (and store channel HTTPClient used for this call) //remove HTTPClient used for this call //IF channel field boolean unsubscribe == true, if so BREAK; //IF connection problem sleep(1500) then CONTINUE //post received data to listeners } } 

Вызов отмены подписки (который будет вызван другим потоком)

 unsubscribe() { //set channel field boolean unsubscribe == FALSE //get channel HTTPClient and shutdown } 

Я выделил проблему, в которой операции чередуются. Для меня это похоже на то, что код многопоточен, а клиентский код не является потокобезопасным. Также плохое управление и повторное использование httpClient не помогает.

Одна из проблем, которые возникают у меня, ниже, когда вызов отписки не останавливает следующий getRequest.

 THREAD 1 (polling) THREAD 2 -------- -------- do unsubscribe check (pass) unsubscribe called set unsubscribe = true check if httpClient saved (none) perform getRequest (save HttpClient first) 

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

Чтобы исправить это, я бы подумал, что httpClient использовать блок syncronisation из первой проверки httpClient подписки на поток 1 вплоть до того, что httpClient сохраняется до того, как выполняется фактический запрос на получение, и синхронизируйте метод отмены подписки с использованием той же блокировки. В настоящий момент это практически невозможно, так как первый упомянутый блок синхронизации запускается в одном вызове метода и заканчивается дальше по цепочке вызовов метода (из-за того, как написана библиотека) – что очень плохо, поэтому потребуется некоторое рефакторинг.

ИЛИ Я мог бы просто создать единственный httpClient каждого канала, а не для каждого запроса, и тогда он всегда может быть выключен, и я могу потенциально игнорировать синхронизацию (я думаю).

ИЛИ, как предложено ниже, я мог бы использовать прерывания для той же цели

Любые предложения приветствуются – я отредактирую, если у меня будет какой-то прогресс!

благодаря

Solutions Collecting From Web of "Проблема параллелизма для аннулирования цикла опроса"

Я купил Java Concurrency на практике в результате этой проблемы и нашел, что они обсуждают проблему, очень похожую на эту в главе 7: Отмена и завершение работы, которые можно суммировать по цитате

Прерывание обычно является наиболее успешным способом реализации отмены

Поскольку HttpClient блокирует сокет IO, который не поддерживает прерывание, поэтому у меня есть два подхода. Я httpClient свой httpClient , я проверяю прерывание непосредственно перед фактическим httpClient.execute() а в моем методе httpClient.getConnectionManager().shutdown(); прерывает поток, а затем вызывает httpClient.getConnectionManager().shutdown(); , Это, похоже, позаботится о моей проблеме и было очень простым изменением. Больше проблем с чередованием!

Я также установил логическое поле отмены unsubscribe на volatile как было предложено, которое я должен был сделать раньше – это одно, однако, не решило бы проблему

1) Отменить подписку как изменчивую

2) Для большей уверенности защитите доступ (чтение / запись), чтобы отказаться от подписки, например, семафором