我试图弄清楚如果新的任务出现取代它,如何取消ThreadPool
中的任务。我有一些类似的类:
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()
}
}
}
}
但是,如果同一RenderableThing
提交到doBackgroundStuff
(已进行更改并需要保存到磁盘),我希望能够取消{{1}之前提交的内容(因为它现在已经过时并且将被覆盖,因此没有理由等待它完成)。问题是,锁定发生在未来尚未存在的范围内。
我知道你永远不应该强行杀死一个被锁定的线程(我甚至不知道怎么回事Future
),所以这样做的正确方法是什么?
修改:我的问题与this one不同,因为我无法取消将来取消它(锁定不会到位,直到ReentrantLock
选择它,到那时ThreadPool
可能已多次提交,而且我不知道哪个会拥有锁。)如果我这样做将是一块蛋糕(处理中断的代码已经到位)。我应该如何更改代码以获取对拥有锁的未来(甚至是线程)的引用?
答案 0 :(得分:0)
我只是想知道这段代码是否有效:
//...
fun doBackgroundStuff(thing: RenderableThing): Future<Stuff> {
L.L.get(thing)?.cancel(true)
val cache = thing.cache()
val f = pool.submit {
try {
thing.lock()
// Do long running I/O task on cache
} finally {
thing.unlock()
}
}
L.L.put(thing, f)
return f
}
//...
object L {
val L: IdentityHashMap<RenderableThing, Future<Stuff>> ? = IdentityHashMap<>()
}