I'm trying to figure out how to cancel a task in a ThreadPool
if a new tasks comes along that supersedes it. I have some classes similar to this:
class RenderableThing {
private val lock = ReentrantLock()
fun lock(interrupt: Boolean) {
if (lock.isLocked && interrupt) {
// How do I interrupt the thread that has the lock?
}
lock.lock()
}
fun unlock() = lock.unlock()
fun cache() = Cached()
inner class Cached()
}
class BackgroundStuff(threads: Int) {
val pool = Executors.newFixedThreadPool(threads)!!
fun doBackgroundStuff(thing: RenderableThing): Future<Stuff> {
val cache = thing.cache()
return pool.submit {
try {
thing.lock()
// Do long running I/O task on cache
} finally {
thing.unlock()
}
}
}
}
However, if the same RenderableThing
gets submitted to doBackgroundStuff
(a change was made and needs to be saved to disk), I would like to be able to able to cancel the Future
of the previous submission (since it's now out of date and will be overwritten, there's no reason to wait for it to finish anymore). The problem is, the locking is taking place inside the future that doesn't exist yet.
I know you're never supposed to force kill a locked thread (I don't even know how since it's a ReentrantLock
), so what is the proper way to do this?
Edit: My question is different from this one as I don't have access to the future to cancel it (the lock isn't put in place till the ThreadPool
picks it up, and by that point the thing
could have been submitted multiple times, and I don't know which would own the lock). If I did it would be a piece of cake (the code to handle interruption is already in place). How should I change my code to get a reference to the future (or even the thread) that owns the lock?