Estoy intentando escribir un rastreador web multiproceso.Uso de Java ThreadPool
Mi clase principal de entrada tiene el siguiente código:
ExecutorService exec = Executors.newFixedThreadPool(numberOfCrawlers);
while(true){
URL url = frontier.get();
if(url == null)
return;
exec.execute(new URLCrawler(this, url));
}
El URLCrawler Obtiene la URL especificada, analiza el código HTML extrae enlaces de ella, y los horarios de enlaces que no se ven de nuevo a la frontera.
Una frontera es una cola de URL no rastreadas. El problema es cómo escribir el método get(). Si la cola está vacía, debe esperar hasta que termine URLCrawlers y vuelva a intentarlo. Debería devolver nulo solo cuando la cola está vacía y no hay actualmente URLrawler activo.
Mi primera idea fue utilizar un AtomicInteger para contar el número actual de URCrawlers activos y un objeto auxiliar para llamadas notifyAll()/wait(). Cada rastreador al inicio incrementa el número de ejecutores URLrawlers en funcionamiento, y al salir lo reduce, y notifica al objeto que se ha completado.
Pero he leído que notify()/notifyAll() y wait() son métodos algo obsoletos para hacer la comunicación de subprocesos.
¿Qué debo usar en este patrón de trabajo? Es similar a M productores y N consumidores, la pregunta es cómo lidiar con la exausación de los productores.
Sí, esa es una solución para un estado estable. ¿Pero cómo lidiar luego con la situación cuando ninguno de URLrawlers pone en cola ninguna URL? Con una cola de bloqueo, la frontera se bloqueará infinitamente. –
En ese caso, puede tener un método crawlerDone() en su objeto de frontera que se llama cada vez que un UrlCrawler termina de funcionar. Este método, junto con el enfoque de contador que sugirió, puede probar (en su método de frontera) si todos los rastreadores han finalizado. Si eso es cierto, get() puede devolver nulo sin bloquear – naikus
frontier puede ser una cola de bloqueo de capacidad fija. un buen candidato para esa capacidad es numberOfCrawlers –