I'm writing a program that will mark an algorithm submitted by a group of students. I plan on copying their algorithm method into the program and running it to see the results; however, it is required that the algorithm not run for more than 10 seconds.
I constructed a ExecutorService to end the algorithm which works for the userInput algorithm (commented out) but did not work for an infinite loop.
From what I know about threads, interrupting it would require altering the algorithm (add a flag), and stopping a thread is depreciated, so is there any other way to end the infinite loop without altering the algorithm in anyway?
Here's the code:
public class TestAlgo{
private String move;
public static void main(String[] args){
TestAlgo testAlgo = new TestAlgo();
testAlgo.runGame();
}
public void runGame(){
Cram game = new Cram();
boolean start = game.startGame();
while (start){
ExecutorService executor = Executors.newSingleThreadExecutor();/////
Future<String> future = executor.submit(new Task());/////
move = "";
try {
System.out.println("Started..");
move = future.get(10, TimeUnit.SECONDS);
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
move = "Timeout";
System.out.println("Terminated!");
} catch (InterruptedException ie){
System.out.println("Error: InterruptedException");
} catch (ExecutionException ee){
System.out.println("Error: ExecutionException");
}
System.out.println("Move: " + move);
executor.shutdownNow();
if (game.sendMove(move)) break;
game.printBoard();
if (game.getMove()) break;
game.printBoard();
}
}
// public static String algorithm(){
// while (true){ //infinite loop
// System.out.println("Algo is running...");
// }
// return "test";
// }
public static String algorithm(){
Scanner userInputScanner = new Scanner(System.in);
System.out.print("Please enter your move: ");
String input = userInputScanner.nextLine();
return input;
}}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
String move = TestAlgo.algorithm();
return move;
}}
Google Guava's SimpleTimeLimiter should help. Simply wrap your
ExecutorService
within theSimpleTimeLimiter
, and then use thecallWithTimeout
method to specify a given timeout period; handle theUncheckedTimeoutException
to indicate that the timeout was reached. Finally, call theshutdown
method of theExecutorService
that was wrapped in theSimpleTimeLimiter
.