Тайм-аут Java-код?

Я пишу онлайн-приложение для программирования Java, где я принимаю код Java в качестве ввода от пользователя и возвращает результаты после компиляции и выполнения через скрипт Python.

Для управления кучей памяти у меня есть стандартное решение использования -Xms и -Xmx при запуске кода в JVM. Я установил Sun Java 1.7.0_40.

Теперь проблема в том, что я запутался в том, как ограничить код ограничением по времени. Например, любой код, представленный пользователем в моем приложении, не должен выполняться дольше T секунд, где T - переменная.

Я написал один простой хак с использованием класса Timer, но проблема в том, что мне нужно использовать много регулярных выражений для внедрения его в код пользователя, которого я в первую очередь хочу избежать. Так как я более удобен в программировании на Python и C++, чем на Java, мне нужно несколько советов о том, существует ли какое-то простое решение для такой проблемы или каковы преимущества и недостатки использования класса Timer.

Любая помощь будет высоко ценится! Спасибо

3 ответа

Решение

Я сделал простой утилитой TimeoutThread, используя ExecutorService.

2 класса:

package eu.wordnice.thread;
/*** Runa.java ***/

import java.util.concurrent.Callable;

public class Runa implements Callable<Object> {

    private Runnable run = null;

    public Runa(Runnable run) {
        this.run = run;
    }

    public Runa(Thread run) {
        this.run = run;
    }

    public Runa() {}

    public Object call() throws Exception {
        if(run != null) {
            run.run();
        }
        return -1;
    };

}

А также:

package eu.wordnice.thread;
/*** TimeoutThread.java ***/
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class TimeoutThread {

    public Runa run = null;
    public ExecutorService executor = null;
    public long timeout = 100L;
    private boolean canceled = false;
    private boolean runed = false;

    public TimeoutThread(Runnable runit, long timeout) {
        this(new Runa(runit), timeout);
    }

    public TimeoutThread(Runa runit, long timeout) {
        this.run = runit;
        if(timeout < 1L) {
            timeout = 10L;
        }
        this.timeout = timeout;
    }


    public Object run() {
        return this.run(false);
    }

    public Object run(Object defaulte) {

        this.runed = true;
        List<Future<Object>> list = null;
        try {
            this.executor = Executors.newCachedThreadPool();
            list = executor.invokeAll(Arrays.asList(this.run), this.timeout, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace();
            this.canceled = true;
        }
        executor.shutdown();

        if(list == null) {
            return defaulte;
        }
        if(list.size() != 1) {
            return defaulte;
        }

        try {
            Future<Object> f = list.get(0);
            try {
                return f.get();
            } catch (Exception e) {
                this.canceled = true;
            }
        } catch (Exception e) { }
        return defaulte;
    }

    public boolean wasRunned() {
        return this.runed;
    }

    public boolean wasCanceled() {
        return this.canceled;
    }

}

Пример:

public static void main(String... blah) {
        TimeoutThread thr = new TimeoutThread(new Runa() {

            @Override
            public Object call() throws Exception {
                while(true) {
                    System.out.println("Yeeee");
                    Thread.sleep(300L);
                }
            }



        }, 500L);
        thr.run();
    }

Распечатать:

Yeeee
Yeeee

РЕДАКТИРОВАТЬ!

Извините, это Timeout Runnable. Если вы хотите Timeout Tread, просто поместите код / ​​вызов в Thread.

public static void main(String... blah) {
        final TimeoutThread thr = new TimeoutThread(new Runa() {

            @Override
            public Object call() throws Exception {
                while(true) {
                    System.out.println("Yeeee");
                    Thread.sleep(300L);
                }
            }



        }, 500L);

        new Thread() {
            @Override
            public void run() {
                thr.run(); //Call it
            }
        }.start(); //Run it
    }

Я хотел бы взглянуть на использование ExecutorService в Java для этого и получить класс с функциональностью, для которой вы хотите использовать тайм-аут, работоспособный, поэтому используйте возможности потоков Java, чтобы помочь вам.

Вы должны быть в состоянии тайм-аут потока, используя следующий код:

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();

Но вам, возможно, придется немного проверить документацию, чтобы заставить ее работать в вашем случае использования.

Смотрите следующий пост для получения дополнительных советов по этому вопросу.

Не уверен, хотите ли вы установить тайм-аут в своем коде Python или в Java, но, надеюсь, это немного поможет.

Ты можешь использовать ThreadPoolExecutor

образец:

int  corePoolSize  =    5;
int  maxPoolSize   =   10; 
long keepAliveTime = 5000;

ExecutorService threadPoolExecutor =
    new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            keepAliveTime,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>()
            );
threadPoolExecutor.execute(new Runnable(){ 

    @Override
    public void run() {
       // execution statements
    });

Рекомендации

  1. http://tutorials.jenkov.com/java-util-concurrent/threadpoolexecutor.html
Другие вопросы по тегам