2011-08-12 283 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; 
     } 
    } 
}