2

We run an AI programming competition in which contestants will code an AI that runs on the JVM using our API we provide them. We put them into a sandbox by limiting what they can do with a SecurityManager, and during runtime they simply set several flags which are their decisions. The only interaction between our system and their AI is through these flags, so there are no bad effects on us if their thread were to suddenly die.

When an AI computes far too long, we would like to shut down their thread. However, we can't find a way of guaranteeing that we will destroy their thread. One possible reason for this is that the AI goes into an infinite loop with no blocking, making Thread.interrupt() useless. Thread.stop() is unreliable since if they are in a try catch block the ThreadDeath exception will be caught, and has no issues for us because they don't touch anything bad and we don't care if they die.

Currently we just ignore their thread and continue on without them after they time out, but their infinite loop will continue processing in the background until the JVM dies. This is unacceptable to us because we will be running matches in the background on a web server 24/7, so we want as much stability as possible. One thought has been to run each game in a separate JVM, but that is far more complex than we would like to get.

Is there any sure fire way to destroy the thread?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303

4 Answers4

0

After trying several things, we came to the conclusion that there is no guaranteed solution. By calling stop() on a thread, that thread is capable of catching the ThreadDeath throwable and ignoring it entirely. Thus, if it's in a while loop continuously catching it, or if it calls a method recursively that catches it, it is not guaranteed that you can kill it.

Since we didn't have any control over the code that would be running in that case, and that code was not necessarily in Java (we were also supporting Jython), the best solution we could come up with was spawning a thread that went into a loop that continuously called suspend() and then stop() on the thread. The result worked for most cases, but occasionally was unable to kill a malicious thread.

  • In this case you should consider moving unsafe part of application to separate JVM process and monitor it. Looks like this is one of safest ways. – Alex Povar Oct 30 '13 at 17:43
0

Provide them with a method they MUST call on a regular basis, even during their computation. If you judge they are 'dead' make the method sleep forever. Obviously his will not work if they are truly dead but you should catch most issues.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
0

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop%28java.lang.Throwable%29

Pass in a custom subclass of Throwable that they can't know about, and you can check their code with the regex: /catch\s*(\s*Throwable/ to ensure that they don't catch Throwable anywhere.

Gus
  • 6,719
  • 6
  • 37
  • 58
0

In general, no, you should not stop an arbitrary thread in a JVM (thus the methods are deprecated). The root of the problem is that you have no idea where in the system the thread is when you kill it. In the worst case it could be in the middle of a synchronized block inside the the JVM's infrastructure that is unprepared for an unexpected exception to be thrown. (Its nearly impossible to write robust synchronized code that can be killed by an exception at arbitrary points.)

See the highly-rated answer on this question for more details: Are java app servers able to destroy threads? If yes, how?

You might be able to get away with a cooperative design where you ask the AI thread to exit. If it does, then you're good. If it does not, then you need to restart the JVM.

Community
  • 1
  • 1
P.T.
  • 24,557
  • 7
  • 64
  • 95