2016-11-24 41 views
0

我想知道如何取消ThreadPool中的任务,如果新任务出现,它将取代它。我有类似这样的一些类:取消Java/Kotlin中的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(一个改动是,需要保存到磁盘),我希望能够能取消Future(因为它现在已过时并将被覆盖,没有理由等待它完成了)。问题是,锁定发生在未来还不存在的地方。

我知道你永远不应该强迫杀死一个锁定的线程(我甚至不知道如何,因为它是一个ReentrantLock),那么做到这一点的正确方法是什么?

编辑:我的问题是从this one不同的,因为我没有进入未来取消它(锁不到位,直到ThreadPool它捡起,并通过该点的thing可能已经提交了多次,我不知道哪个会拥有锁)。如果我这样做了,那将是小菜一碟(处理中断的代码已经到位)。我应该如何更改我的代码以获取对拥有锁的未来(甚至线程)的引用?

+0

难道你不知道'Future'有一个名为'cancel'方法? – glee8e

+0

[Java执行程序:我怎样才能停止提交的任务?](http://stackoverflow.com/questions/1418033/java-executors-how-can-i-stop-submitted-tasks) – glee8e

+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<>() 
} 
+0

不,那会保留所有的'RenderableThing',我只想删除它,如果它是同一个。我已经尝试过类似的代码(但把它放在'RenderableThing'来解决这个问题),但遇到了问题,因为延迟锁定意味着在此期间发生了任何事情。 –

+0

其实,修改你的代码,将其与我之前做的事情混合,可能只是解决了我的问题。让我进行一些测试。 –

+0

@ RuckusT-Boom更新时间 – glee8e