首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以智能方式使计算线程可取消

以智能方式使计算线程可取消
EN

Stack Overflow用户
提问于 2013-11-24 21:13:49
回答 2查看 140关注 0票数 2

我想知道如何在快速取消响应性和性能之间达成妥协,我的线程的主体看起来类似于这个循环:

代码语言:javascript
复制
for(int i=0; i<HUGE_NUMBER; ++i) {
    //some easy computation like adding numbers
    //which are result of previous iteration of this loop
}

如果循环体中的计算非常容易,那么在每个迭代中添加简单的检查反应:

代码语言:javascript
复制
if (Thread.currentThread().isInterrupted()) {
    throw new InterruptedException("Cancelled");            
}

允许减慢代码的执行速度。

即使我将上述条件更改为:

代码语言:javascript
复制
if (i % 100 && Thread.currentThread().isInterrupted()) {
    throw new InterruptedException("Cancelled");            
}

然后编译器不能仅在某些特定情况下预计算i的值和检查条件,因为HUGE_NUMBER是可变的,可以有不同的值。

因此,我想问一下,是否有任何智能方式()可以将这样的检查添加到所呈现的代码中,同时知道:

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

我想说的是,循环的一次迭代是相当快的,但是迭代的HUGE_NUMBER可能需要更多的时间,这就是我想要避免的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-24 21:38:11

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

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

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

不要做像if (i % 10000 == 0)这样的把戏,因为这会比“短”Thread.interrupted()慢得多。

您可以使用一个小技巧--但是要三思,因为它会使您的代码变得更加复杂和可读性更低:

每当你有这样的循环时:

代码语言:javascript
复制
for (int i = 0; i < max; i++) {
    // loop-body using i
}

您可以将i的总范围划分为大小INTERVAL_SIZE的几个间隔。

代码语言:javascript
复制
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)上做了一些测试

代码语言:javascript
复制
if (i % 2 == 0) x++;

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

  • 没有任何中断检查的简单循环:1,949 ms
  • 每次迭代检查的简单循环:2,219 ms (+14%)
  • 使用模块化:3,166 ms (+62%)进行每百万次迭代检查的简单循环
  • 使用位掩码进行每百万次迭代检查的简单循环:2,653 ms (+36%)
  • 正如上面描述的带签入外循环的间隔环:1,972 ms (+1.1%)

因此,即使循环体像上面那样简单,每次迭代检查的开销也只有14%!因此,建议不要做任何技巧,但只需在每次迭代中通过检查中断标志!

票数 2
EN

Stack Overflow用户

发布于 2013-11-24 21:37:59

使您的计算成为Iterator

虽然这听起来不太有用,但这里的好处是您可以很容易地编写过滤器迭代器,这些迭代器非常灵活。他们可以添加和删除简单-即使通过配置,如果你愿意。有很多好处--试试吧。

然后,您可以添加一个过滤Iterator,它定期监视时间并检查中断--甚至更灵活。

您甚至可以在不影响原始计算的情况下添加进一步的筛选,方法是将原始计算与脆性状态检查相加。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20181097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档