tiene problemas con la comunicación entre subprocesos y lo "resuelve" usando "mensajes ficticios" por todas partes. ¿Es una mala idea? ¿Cuáles son las posibles soluciones?Comunicación interproceso productor-consumidor
Ejemplo de problema que tengo.
El hilo principal inicia un hilo para procesar e insertar registros en la base de datos. hilo principal lee un archivo posiblemente enorme y coloca un registro (objeto) tras otro en una cola de bloqueo. el hilo de procesamiento lee de la cola y funciona.
¿Cómo digo "proceso de hilo" para detener? La cola puede estar vacía pero el trabajo no está terminado y el hilo principal no está ahora cuando el hilo de procesamiento ha terminado de funcionar y no puede interrumpirlo.
hilo para el procesamiento hace
while (queue.size() > 0 || !Thread.currentThread().isInterrupted()) {
MyObject object= queue.poll(100, TimeUnit.MILLISECONDS);
if (object != null) {
String data = object.getData();
if (data.equals("END")) {
break;
}
// do work
}
}
// clean-up
synchronized queue) {
queue.notifyAll();
}
return;
hilo principal y
// ...start processing thread...
while(reader.hasNext(){
// ...read whole file and put data in queue...
}
MyObject dummy = new MyObject();
dummy.setData("END");
queue.put(dummy);
//Note: empty queue here means work is done
while (queue.size() > 0) {
synchronized (queue) {
queue.wait(500); // over-cautios locking prevention i guess
}
}
Tenga en cuenta que la inserción esté en la misma transacción y transacción no puede ser manejado por hilo principal.
¿Cuál sería una mejor forma de hacerlo? (Estoy aprendiendo y no quiero comenzar a "hacerlo de la manera incorrecta")
Ok. ¿Cómo usaría esto si el tipo de objetos pasados no tiene un campo String que pueda usarse fácilmente para esto? ¿Qué pasa si algún texto podría ser datos válidos y por lo tanto podría ser igual al veneno? Use un GUID? –
Lo ideal sería cambiar la clase MyObject y agregar un método isPoison() allí. La forma en que este método determina si el objeto es un veneno o no depende de usted; puede ser algo simple como comparar si el mensaje es nulo, está vacío o si el mensaje fue creado explícitamente como veneno. Una idea sería refactorizar MyObject para que sea una interfaz con dos implementaciones, un MessageObject que siempre devuelve falso en el método isPoison() y un PoisonMessage, que siempre devuelve verdadero. Pero esto depende profundamente de qué es exactamente lo que está haciendo, y pueden existir mejores soluciones dado su contexto real. –