Time out a java code?

4.9k Views Asked by At

I am writing an online java programming app where I take a java code as input from user and returns the output after compilation and execution through a python script.

For controlling the memory heap I have a standard solution of using -Xms and -Xmx while running the code in JVM. I have installed Sun Java 1.7.0_40.

Now the problem is that I am confused about how to restrict the code with a time limit. For example any code submitted by user in my app should not run for more than T seconds, where T is a variable.

I wrote one simple hack using Timer class but the problem is I have to use a lot of regex to inject it in the user code which I primarily want to avoid. As I am more comfortable in python and c++ than java as a programmer, I need some guidance about whether there exists some easy solution for such problem or what are the pros and cons of using the Timer class.

Any help will be much appreciated! Thanks

3

There are 3 best solutions below

0
On BEST ANSWER

I've done simple 'TimeoutThread' util using by ExecutorService.

2 classes:

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

}

And:

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

}

Example:

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

Print:

Yeeee
Yeeee

EDIT!

Sorry, that is Timeout Runnable. If you want Timeout Tread, just put the code / call into 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
    }
0
On

I would have a look at using ExecutorService in Java for this and have the class with the functionality you want to time out implement runnable - so using Java's threading capabilities to help you out.

You should be able to timeout the thread using the following code:

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

But you may need to check out the documentation a bit to get it to work for your use case.

See the following post for more advice on this kind of thing.

Not sure if you're wanting to have the timeout in your python code or in Java, but hopefully this'll help a bit.

0
On

You can use ThreadPoolExecutor

sample:

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

References

  1. http://tutorials.jenkov.com/java-util-concurrent/threadpoolexecutor.html