I am coding a client/socket connection and I am using ThreadPools to handle several clients.
After my Server has started I have several Resouces used. I want to close all of them if f.ex.: the server says to the client it should shutdown, I want to close everything.
I still coded a basic shutdown function:
public static void killClient() {
try {
threadpool.shutdown();
in.close();//client input
out.close();//client output
socket.close();
} catch(Exception e) {
System.out.println("Client has been shutdown! " + e);
e.printStackTrace();
}
}
My question is:
How to be sure that everything has closed propely and nothing still runs anymore?
I’ve answered the specific question below.
I think that it is more important to “close” your classes as opposed to concentrating on closing the resources. If a class (such as your
Clientclass above) wraps resources such as a thread-pool and sockets, then it should have aclose()method on it (such as yourkillClient()above). If the server forks a client then it should manage them so that aserver.close()calls the variousclient.killClient()methods.If you get religious about properly shutting down the various classes, using
try {} finally {}blocks everywhere, you should not have to worry about unclosed resources and hung threads.This is hard to do and there is no blanket answer for all resource types. Here’s a couple of ideas that might help.
For threads you can use something like
Threads.getAllStackTraces()to show what threads are left. If you compare this list when your program starts and then when it finishes you should be able to see what’s left.File descriptors are a lot harder. If you are running on Linux then you can look at the
/proc/self/fddirectory to see what descriptors are still open. Again compare start and end. You can also look at theOpenFileDescriptorCountJMX variable (java.lang:type=OperatingSystem) in your application but that just gives the number of descriptors without context.There is no easy way to detect leaks in other resources. You could wrap a
ResourceManagertype class around them from which you “generate” and “release” a resource but this requires programming support. If you create a resource outside of the manager there is no easy way to detect the leak.One example of a such a mechanism is what I do for ORMLite testing. ORMLite opens and closes a lot of database connections and I wanted to make sure I wasn’t bleeding them in my code. I created a wrapper around database connections that would register themselves with a manager when they were created and un-register themselves when they were closed. Then I could make sure that
assertTrue(connectionManager.isAllConnectionsClosed());. Not sure if that’s helpful.