user1386101
user1386101

Reputation: 1944

Need advice on ExecutorService in java

Hey so I picked up this example for the java docs for ExecutorService. I wanted to confirm the flow of this code, the Executors.newFixedThreadPool will create a pool of threads(I guess). So the serversocket will wait for a connection and once it acquires one, it starts a thread, so now the poolsize decrease by 1. Once the thread finishes execution, the poolsize will again increment by 1, wont it? Will the thread give up the resources it used?

class NetworkService implements Runnable {
 private final ServerSocket serverSocket;
 private final ExecutorService pool;

 public NetworkService(int port, int poolSize)
   throws IOException {
 serverSocket = new ServerSocket(port);
 pool = Executors.newFixedThreadPool(poolSize);
}

 public void run() { // run the service
 try {
   for (;;) {
     pool.execute(new Handler(serverSocket.accept()));
   }
 } catch (IOException ex) {
   pool.shutdown();
  }
 }
}

class Handler implements Runnable {
 private final Socket socket;
 Handler(Socket socket) { this.socket = socket; }
 public void run() {
  // read and service request on socket
 }
}

Upvotes: 1

Views: 719

Answers (3)

Gray
Gray

Reputation: 116828

Once the thread finishes execution, the poolsize will again increment by 1, wont it?

Yes. The thread will go to take and run the next Handler.

Will the thread give up the resources it used?

Not immediately, no. Once the Handler run() method has finished then the Handler will go out of scope. However, you have to wait for the garbage collector to run before the Handler instance is released. This will in turn release Socket which then be a candidate for garbage collection itself.

If you want your Socket to be released sooner (which I assume is the problem) then that should be done at the end of the run() method. You can call socket.close() (and maybe set socket to be null) in a finally block. Something like the following is recommended:

class Handler implements Runnable {
    ...
    public void run() {
       try {
           // read and service request on socket
       } finally {
           // make sure we close the socket when the handler is finishing
           socket.close();
       }
    }
}

Upvotes: 1

Zak
Zak

Reputation: 7078

Since it is a fixedThreadPool, yes, the pool size is reduced everytime a task is submitted to the pool & increased once a thread is done running the submitted runnable (or callable). Submitting more number of runnables to a fixed thread pool will block until any of the threads in the pool are done running their tasks submitted earlier.

Upvotes: 0

Cratylus
Cratylus

Reputation: 54074

All the threads do is execute your Runnables.
So if you need to do any clean after what your task did you should do it from your Runnable. The pool is just a Producer-Consumer pattern implementation and is responsible for managing the life-cycle of the threads.
The threads executes the tasks you pass in the queue so in your case, the socket is not reused among threads. It's scope is inside the Runnable

Upvotes: 0

Related Questions