gpt4 book ai didi

java - 以智能方式取消计算线程

转载 作者:行者123 更新时间:2023-11-30 08:28:28 25 4
gpt4 key购买 nike

我想知道如何在我的线程中实现快速取消响应和性能之间的折衷,线程的主体看起来类似于此循环:

for(int i=0; i<HUGE_NUMBER; ++i) {
//some easy computation like adding numbers
//which are result of previous iteration of this loop
}

如果循环体中的计算非常简单,则在每次迭代中添加简单的检查 react :

if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Cancelled");
}

可能减慢代码的执行。

即使我把上面的条件改成:

if (i % 100 && Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Cancelled");
}

由于 HUGE_NUMBER 是可变的并且可以具有不同的值,因此编译器不能仅预先计算 i 的值并仅在某些特定情况下检查条件。

所以我想问一下,是否有任何聪明的方法将此类检查添加到呈现的代码中,知道:

  • HUGE_NUMBER 是可变的,可以有不同的值
  • 循环体由一些易于计算但依赖于先前计算的代码组成。

我想说的是,循环的一次迭代非常快,但是 HUGE_NUMBER 次迭代可能会花费更多时间,这是我想要避免的。

最佳答案

首先,在这种情况下使用 Thread.interrupted() 而不是 Thread.currentThread().isInterrupted()

您应该考虑检查中断标志是否真的会大大减慢您的计算速度!一方面,如果循环体非常简单,即使是大量的迭代(上限为 Integer.MAX_VALUE)也会在几秒钟内运行。即使检查中断标志会导致 20% 或 30% 的开销,这也不会增加算法的总运行时间。

另一方面,如果循环体不是那么简单,那么它会运行更长时间,我认为测试中断标志不会是一个显着的开销。

不要做像 if (i % 10000 == 0) 这样的技巧,因为这比“短”Thread.interrupted() 更能减慢计算速度>.

您可以使用一个小技巧 - 但请三思,因为它会使您的代码更复杂且可读性更差:

每当你有这样的循环时:

for (int i = 0; i < max; i++) {
// loop-body using i
}

您可以将 i 的总范围分成几个大小为 INTERVAL_SIZE 的区间:

int start = 0;
while (start < max) {
final int next = Math.min(start + INTERVAL_SIZE, max);
for(int i = start; i < next; i++) {
// loop-body using i
}
start = next;
}

现在您可以在内循环之前或之后添加中断检查!


我已经使用以下循环体在我的系统 (JDK 7) 上完成了一些测试

if (i % 2 == 0) x++;

Integer.MAX_VALUE/2 次迭代。结果如下(预热后):

  • 没有任何中断检查的简单循环:1,949 毫秒
  • 每次迭代检查的简单循环:2,219 毫秒 (+14%)
  • 使用模数每 100 万次迭代检查一次的简单循环:3,166 毫秒 (+62%)
  • 使用位掩码每 100 万次迭代检查一次的简单循环:2,653 毫秒 (+36%)
  • 如上所述的间隔循环并检查外循环:1,972 毫秒 (+1.1%)

所以即使循环体像上面一样简单,每次迭代检查的开销也只有 14%!所以建议不要做任何技巧,而是在每次迭代中通过 Thread.interrupted() 简单地检查中断标志!

关于java - 以智能方式取消计算线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20181097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com