- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
鉴于我有以下测试代码:
import java.util.concurrent._
object TestTime {
def main(args: Array[String]) {
println("starting....")
val service = Executors.newSingleThreadExecutor
val r = new Callable[Unit]() {
override def call(): Unit = {
//your task
val t0 = System.nanoTime
val total = sum(1000000000)
val t1 = System.nanoTime
println("Elapsed time " + (t1 - t0) / 1e9 + " secs")
println(s"total = $total")
}
}
val f = service.submit(r)
try {
// attempt the task for 2 second
f.get(2, TimeUnit.SECONDS)
} catch {
case _: TimeoutException =>
f.cancel(true)
println(s"Timeout....")
} finally {
service.shutdown()
}
println("after 2 seconds....")
for(i <- 1 to 2){
println(s"$i ...")
Thread.sleep(1000)
}
println("main thread ends...")
}
//Given that sum() is written by others and I cannot change it.
def sum(k: Int): BigInt = {
var total: BigInt = 0
for (i <- 1 to k) {
total += i
}
total
}
}
我想最多执行 sum
2 秒。如果超过时间限制,则应立即中断相应的线程。为了中断该线程,我在 catch TimeoutException
时尝试了两种方法:
f.cancel(true)
service.shutdownNow()
但是根据我的测试,以上方法都无法中断线程。
所以我想知道是否有方法强制中断线程。
最佳答案
根据 JavaDocs Future#cancel
和 ExecutorService#shutdownNow
,典型的实现是这些方法会导致底层线程中断。
If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
特别注意最后一条评论。通过 Thread#interrupt
线程中断方法是一个合作过程。当一个线程中断另一个线程时,会导致设置目标线程的中断状态。此外,如果目标线程在某些特定方法中被阻止,那么该线程将遇到 InterruptedException
.
如果目标线程中执行的代码既不通过 Thread#isInterrupted
定期检查中断状态,方法也不调用阻塞方法并处理 InterruptedException,则中断实际上不执行任何操作。该代码在中断过程中不配合,因此尽管线程中断,但实际上无法将其关闭。
//Given that sum() is written by others and I cannot change it.
理想情况下,将更改旨在在后台线程中执行的长时间运行的代码以配合线程中断。在您的示例中,一种可行的技术是更改 sum
以在 for
循环的每 N 次迭代中检查 Thread#isInterrupted
,如果中断,中止循环。然后,它可以抛出异常来指示它未完成,或者可能返回一些哨兵 BigInt
值来指示中止(如果合适)。
如果调用的代码确实无法更改,则无法通过线程中断来停止它。您可能会使用 daemon threads这样至少这些线程不会在关闭期间阻止 JVM 退出。
关于java - 如何在 Java/Scala 中中断提交给 newSingleThreadExecutor 的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45106542/
我是一名优秀的程序员,十分优秀!