2011-08-12 286 views
3

我在我的代码中嵌入Groovy运行时,我希望能够中断它。我无法控制将要运行的脚本。我读了groovy.transform.ThreadInterrupt处理线程中断,但由于某些原因,下面的代码不能按预期工作。它实际上等待10000毫秒而不是1000应该被中断的地方。停止执行Groovy脚本

任何想法?谢谢。

import groovy.lang.Binding; 
import groovy.lang.GroovyShell; 
import groovy.transform.ThreadInterrupt; 
import org.codehaus.groovy.control.CompilerConfiguration; 
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; 

public class GroovyTest extends Thread { 
    private Binding binding; 
    private GroovyShell shell; 

    public GroovyTest() { 
     CompilerConfiguration compilerConfig = new CompilerConfiguration(); 
     compilerConfig.addCompilationCustomizers(
       new ASTTransformationCustomizer(ThreadInterrupt.class)); 

     binding = new Binding(); 

     shell = new GroovyShell(this.getClass().getClassLoader(), binding, compilerConfig); 
    } 

    @Override 
    public void run() { 
     System.out.println("Started"); 

     shell.run("for(int i = 0; i < 10; i++) {sleep(1000)}", "test", new String[] {}); 

     System.out.println("Finished"); 
    } 

    public static void main(String args[]) throws InterruptedException { 
     GroovyTest test = new GroovyTest(); 

     test.start(); 

     System.out.println("Sleeping: " + System.currentTimeMillis()); 

     Thread.sleep(1000); 

     System.out.println("Interrupting: " + System.currentTimeMillis()); 

     test.interrupt(); 
     test.join(); 

     System.out.println("Interrupted?: " + System.currentTimeMillis()); 
    } 
} 

回答

4

回答我自己的问题。 即使您试图在没有闭包的情况下,Groovy的静态方法sleep也不会中断。 如果你问我,很奇怪的默认设置。 推荐的方法是调用Thread.sleep(ms)

private static void sleepImpl(long millis, Closure closure) { 
    long start = System.currentTimeMillis(); 
    long rest = millis; 
    long current; 
    while (rest > 0) { 
     try { 
      Thread.sleep(rest); 
      rest = 0; 
     } catch (InterruptedException e) { 
      if (closure != null) { 
       if (DefaultTypeTransformation.castToBoolean(closure.call(e))) { 
        return; 
       } 
      } 
      current = System.currentTimeMillis(); // compensate for closure's time 
      rest = millis + start - current; 
     } 
    } 
}