Potresti usare dei pool di thread con l'ExecutorService.
L'ExecutorService accetta degli oggetti Callable che sono dei task che restituiscono un valore (a differenza dei Runnable) e li esegue contemporaneamente con i thread. Leggi un po' qui.
Per ricercaKinder, al posto di usare un Lock, puoi usare il modificatore synchronized.