Это не то, что вы можете сделать на 100% надежно в JVM. Единственный способ остановить что-то через некоторое время - это дать ему новый поток, а затем отправить этому потоку исключение, когда вы хотите, чтобы это прекратилось. Но их код может перехватить исключение, или они могут раскрутить другой поток, который вы не контролируете, или ...
Но в большинстве случаев, особенно если вы контролируете тайм-аут кода, вы можете сделать что-то похожее на то, что мы делаем в clojail :
Если вы хотите сделать это красивее, вы можете определить макрос как
(defmacro with-timeout [time & body]
`(thunk-timeout (fn [] ~@body) ~time))