Thread spawning child threads and waiting for children to finish
Instead of creating threads use an ExecutorService and use invokeAll(Collection&lt;Callable&gt;, long, timeUnit). This will return when all calls are done or the timeout expires whichever happens first. Tasks that aren't completed will be canceled (which can be checked by the isCanceled() property of the matching Future in the return value).

This will mean you will need to change the Runnables to Callables but that just means returning null in the call method.