Edit:
after rereading the question I am not sure any more if you have access to the client code. If you do, well you can revise it and not even use thread but java.util.concurrent.ExecutorService
or the likes.. yet
Since the code is not your own... you are on your own to stop it.
ThreadGroup class is designed for. Managing partial programs or modules is not exactly easy and usually it takes some already established framework. Ensuring some 3rd party code will behave and be nice and all it's not always possible. It should include context classloader and what not but here is a skimmed version of how it's done.
Still there might be something you can do to break the bone of the intruder. Assuming stop()/close(), etc has been used, some tricks like ThreadDeath during logging and so on.
ThreadGroup g=new ThreadGroup("client X group");
Runnable r=new Runnable(){
public void run(){
client.doSmth();//assuming a new thread is started...
}
}
Thread t= new Thread(g, r, "clientStarter");
t.start();
//stopping, last resort code, it's usually more complicated than just thread.stop, though
//now you can enumerate threads of the ThreadGroup
synchronized(g){//sync ensures no more threads will be created, use it w/ extreme caution
Thread[] threads = new Thread[g.activeCount()];
for(Thread thread:threads){
if(thread==null) break;
thread.stop();//
//cannot join in sync of ThreadGroup, do not use it here
}
}
Good luck!