【问题标题】:Java thread interruption won't work for me (in groovy)Java线程中断对我不起作用(在groovy中)
【发布时间】:2017-09-05 17:01:36
【问题描述】:

我现在正试图为一个已经在 groovy 中工作了几个小时的线程获得一个简单的中断。

不知何故,以下代码不会在线程“名称”中设置“中断”标志。导致循环运行直到结束。

发现了很多其他问题,通常缺少Thread.currentThread().isInterrupted() 的检查。但这里不是这样:

def t = Thread.start('name') {
    try {
        for (int i = 0; i < 10 && !Thread.currentThread().isInterrupted(); ++i) {
            println "$i"
            sleep 1000
        }
    } catch (InterruptedException e) {
        println "Catched exception"
        Thread.currentThread().interrupt();
    }
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
sleep 2000

我得到以下输出

Interrupting thread in 1...
0
Interrupting thread...
1
2
3
4
5
6
7
8
9

想知道我在这里想念什么/做错了吗? 还尝试使用 ExecutorService 并在返回的 Future 上调用 cancel(true)。也没用。

【问题讨论】:

    标签: multithreading groovy interrupted-exception


    【解决方案1】:

    如果在sleeping 时中断线程,则Thread.sleep 抛出的休眠中断线程catchesInterruptedException 并清除中断状态。所以你的Thread.currentThread().isInterrupted() 总是返回false

    如果您将sleep 1000 替换为Thread.sleep(1000),您可以使您的代码工作。

    【讨论】:

      【解决方案2】:

      TL;DR:不要使用Thread中断作为中止标准,而是使用一些自定义标志。


      您使用的不是Thread.sleep(),它会抛出InterruptedException,而是GDKs Object.sleep(),它处理并忽略中断:http://docs.groovy-lang.org/docs/groovy-2.4.7/html/groovy-jdk/java/lang/Object.html#sleep(long)

      要么使用Thread.sleep(),而是使用:(在你的情况下,在 catch 块中中断是无用的)

      def t = Thread.start('name') {
          try {
              for (int i = 0; i < 10 && !Thread.interrupted(); ++i) {
                  println i
                  Thread.sleep 1000
              }
          } catch (InterruptedException e) {
              println "Catched exception"
          }
      }
      println "Interrupting thread in 1..."
      sleep 1000
      println "Interrupting thread..."
      t.interrupt()
      

      或者使用Object.sleep() 的变体和Closure 并在那里中止你的循环,例如。 G。通过投掷InterruptedException 喜欢:

      def t
      t = Thread.start('name') {
          try {
              for (int i = 0; i < 10 && !Thread.interrupted(); ++i) {
                  println i
                  sleep(1000) {
                      throw new InterruptedException()
                  }
              }
          } catch (InterruptedException e) {
              println "Catched exception"
          }
      }
      println "Interrupting thread in 1..."
      sleep 1000
      println "Interrupting thread..."
      t.interrupt()
      

      解决了你的困惑之后,现在让我建议不要做你想做的事。中断绝不是用作中止条件的好方法。由于各种原因,睡眠或阻塞 IO 总是会被中断。更好的方法是让你的运行循环检查一些 boolean 标志,你可以切换到中止工作。

      【讨论】:

      • 感谢您的详细解释。应该注意到,首先我使用自定义标志让它工作;然而,在网上搜索后,我发现很多帖子告诉人们应该使用内置的中断功能来停止线程的执行。但可能那只是为了java。只是为了澄清一下:我不会在同步那个写在一个线程中并在另一个线程中读取的标志方面遇到麻烦?
      • Java 或 Groovy 在这里没有区别。我的建议实际上是针对 Java 的,但对于 Groovy 也是如此,因为它是基于 Java 构建的。实际上,尽可能使用执行器和任务而不是线程更好,因为它们是经过彻底编写和测试的。但是,是的,您当然必须同步对该标志变量的访问,才能安全地从多个线程修改和访问它。
      猜你喜欢
      • 2015-09-03
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      相关资源
      最近更新 更多