Остановка выполнения скрипта Groovy

Я встраиваю среду выполнения Groovy в свой код и хотел бы иметь возможность прерывать ее. У меня нет контроля над сценариями, которые будут запускаться. Я читал о groovy.transform.ThreadInterrupt для обработки прерываний потока, но по какой-то причине этот код ниже не работает должным образом. На самом деле он ожидает 10000 мс вместо 1000, когда он должен быть прерван.

Есть идеи? Спасибо.

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());
    }
}

person Clueless    schedule 12.08.2011    source источник


Ответы (1)


Отвечая на мой собственный вопрос. Статический метод 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;
        }
    }
}
person Clueless    schedule 13.08.2011