Emisión de concurrencia para la cancelación del bucle de encuesta larga

Tengo un problema que espero resolveré escribiendo esta pregunta pero si no voy a publicar y ver si alguien puede ayudar.

Estoy utilizando una biblioteca de cliente (que está mal escrito me siento) para interactuar con un servidor de chat en tiempo real que utiliza el estilo de COMET largo de sondeo a través de HTTP. Tengo problemas con la cancelación de la encuesta larga en ciertas situaciones y sospecho que puede que tenga que añadir algún código de manejo de concurrencia, pero estoy encontrando difícil encontrar la mejor manera de hacer esto por las siguientes razones.

El código de suscripción (que inits el sondeo largo) se implementa como un bucle grande con el siguiente

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 } } 

La llamada unsubscribe (que llamará a otro hilo)

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

He aislado el caso del problema donde las operaciones son entrelazado. A mí esto parece un resultado del código que es multi-hilo y el código del cliente que no es hilo seguro. También mala gestión y no reutilización del httpClient no está ayudando.

Uno de los problemas que tengo es por debajo de donde la llamada unsubscribe no detiene la próxima getRequest de tener lugar.

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

Me gustaría saber lo que la gente piensa que el mejor enfoque para este problema sería (el tiempo también es limitado por lo que no puedo reescribir demasiado del código!)

Para solucionar esto, pensé que podría utilizar un bloque de sincronización de la primera httpClient la suscripción comprobar en el hilo 1 hasta el punto de la httpClient se guarda justo antes de la solicitud de obtener real se realiza y sincronizar el método unsubscribe utilizando el mismo bloqueo. Esto no es práctico en este momento ya que el primer bloque de sincronización mencionado comenzaría en una llamada de método y terminaría más abajo en la cadena de llamada de método (debido a cómo se escribe la lib), lo que se siente muy mal, por lo que se necesitaría alguna refactorización.

O podría crear un único httpClient por canal en lugar de por solicitud y, a continuación, siempre podría ser apagado y podría potencialmente ignorar la sincronización (creo).

O como se sugiere a continuación, podría utilizar interrupciones para el mismo propósito

Cualquier sugerencia sería bienvenida – voy a editar si tengo algún progreso!

Gracias

Compré Java Concurrency en la práctica como resultado de este problema y encontró que discutir un tema muy similar a éste en el Capítulo 7: Cancelación y cierre que puede resumirse por la cita

La interrupción suele ser la forma más exitosa de implementar la cancelación

Como el HttpClient está bloqueando socket IO que no soporta interrupción así que tengo un enfoque de dos puntas. httpClient mi httpClient , compruebo para la interrupción apenas antes de la httpClient.execute() real de httpClient.execute() y en mi método del unsubscribe() interrumpo el hilo y entonces llamo httpClient.getConnectionManager().shutdown(); . Esto parece cuidar de mi problema y fue un cambio muy simple. No más problemas de intercalación!

También establecí el campo booleano de anular unsubscribe a volatile como se sugirió lo que debería haber hecho antes – esto por sí solo sin embargo no habría resuelto el problema

1) Establecer unsubscribe como volátil

2) Para mayor seguridad, proteja el acceso (lectura / escritura) para cancelar la suscripción con, por ejemplo, un Semáforo

  • Synchronize ("Cache_Group") parte se omite, ¿por qué es así?
  • Cómo conectar un teléfono HTC android a la PC como dispositivo de depuración
  • SQLiteOpenHelper sincronización
  • ¿Posee un adaptador de sincronización para Android?
  • Adaptador de sincronización de contactos en android
  • ¿Cómo notificar a la actividad de llamada cuando SyncAdapter ha finalizado?
  • ¿Cómo sincronizar el acceso a sqlite db entre el primer plano y el proceso en segundo plano?
  • Cuándo utilizar sincronizado en Java
  • Android sync / descargar marco
  • Buscando información sobre el Administrador de sincronización de Android
  • Mejor manera de sincronizar contactos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.