Hello. I am trying to make a thread pool for a server that will process incoming socket connections. The purpose is to have limited available connections at a time.
I can't grasp this concept fully to implement it. Perhaps some of you can help me! Please try.

Below is my current thread "launcher"

while (listening){
            System.out.println("Listening...");
	    new MyServerThread(serverSocket.accept()).start();
        }

But i don't understand how to do it through a fixedThreadPool.

My speculations
As far as i understand, though, is that i need to satisfy the following steps: (Correct me if i'm wrong!)
* Design a ThreadFactory that will create my threads.
* Make a pool of desired maxNr of threads; associate my ThreadFactory to it.
* On an incoming connection: invoke any thread, sending to it the client's socket connection. (after the thread will finish it will wipe client's socket connection)
But the problem here is that i can't find a way to send the client's socket to the thread.

Possbile solution
I could instantiate all the threads beforehand, then launch them all to race for the first client. But that would mean that i have to constantly launch the ones that have just finished, thus currentRunningThreads=maxNrOfThreads, always. Totally not elegant.

Dani AI

Generated

A short, practical summary that fills the gaps in the thread: was right to suggest separating the “task” (handle one client) from the thread mechanics. The typical, robust pattern is: accept the Socket, wrap it in a Runnable (or Callable) that owns the Socket, and submit that Runnable to a thread pool. The Runnable closes the socket when done. That is how the socket gets “sent” to a worker.

Example skeleton (illustrates the ideas; adapt imports and error handling):

int maxThreads = 10;
int queueSize = 50;
ThreadPoolExecutor pool = new ThreadPoolExecutor(
    maxThreads, maxThreads, 0L, TimeUnit.MILLISECONDS,
    new ArrayBlockingQueue<Runnable>(queueSize),
    Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.AbortPolicy()
);

class ClientHandler implements Runnable {
    private final Socket socket;
    ClientHandler(Socket socket) { this.socket = socket; }
    public void run() {
        try (Socket s = socket;
             InputStream in = s.getInputStream();
             OutputStream out = s.getOutputStream()) {
            // protocol handling here
        } catch (IOException e) {
            // log
        }
    }
}

/* accept loop */
while (running) {
    Socket client = serverSocket.accept();
    try {
        pool.execute(new ClientHandler(client));
    } catch (RejectedExecutionException ex) {
        // pool queue full: politely refuse and close socket
        client.close();
    }
}

Important operational notes and alternatives:

  • Do not use Executors.newFixedThreadPool() blindly: it uses an unbounded queue by default, which can exhaust memory if connections arrive faster than they are processed. Use a ThreadPoolExecutor with a bounded queue and a rejection policy (or a custom RejectedExecutionHandler) to apply backpressure.
  • To avoid accepting more sockets than can be held in the kernel backlog, consider gating accepts with a Semaphore (acquire before accept, release in the handler finally block). That blocks new accept() calls when the server is at capacity instead of creating many queued tasks/objects.
  • Always close sockets in a finally/try-with-resources, handle IOExceptions, and provide a clean shutdown path (pool.shutdown(), serverSocket.close(), then awaitTermination).
    These points give a controlled, predictable way to limit concurrent processing while keeping resource usage bounded.

Recommended Answers

All 2 Replies

The purpose is to have limited available connections at a time

Are you sure it's limited number of "connections" you are looking into or is it limited number of serviceable connections? Because the way you have presented your sample snippet, you would anyways be consuming a "socket" on the server side, with the difference being the total number of client requests concurrently being handled/processed.

Anyways, I think the confusion here stems from the fact that you are creating a special kind of thread (MyServerThread) rather than creating a runnable which in turn can be processed by threads i.e. separate the notion of a single request handling task from the notion of how it is serviced (i.e. one thread per request, one thread for all requests, a pool of threads for all requests etc.)

Also, is creating your own thread pool and absolute requirement here since that might involve a lot of thorough testing on your part and still might not turn out to be perfect. If no, then you can use the concept of Executor service which was introduced in Java 5, specifically the fixed thread pool executor.

The Javadocs of the ExecutorService interface has an example which perfectly fits your use-case.

Thanks for replying. I just wanted to say that i'm busy now and that i solved my problem, but in a less elegant way.So I'll get back to this thread later.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.