Socket server-A TCP server based on the thread pool

Source: Internet
Author: User

Understanding Thread Pools

In http://blog.csdn.net/ns_code/article/details/14105457 (reading note one: TCP Socket) In this blog post, the server-side implementation is: a client corresponding to a thread. However, each new thread consumes system resources: Creating a thread consumes CPU cycles, and each thread builds its own data structures (such as stacks), consumes system memory, and when one thread blocks, the JVM saves its state, selects another thread to run, and restores the state of the blocked thread when the context switch is being converted. As the number of threads increases, the threads will consume more and more system resources, which will eventually result in the system spending more time dealing with context conversion box thread management and less time servicing the connection. In this case, adding an additional thread may actually increase the client's total service time.

We can avoid this problem by limiting the total number of threads and reusing threads. We have the server create a thread pool that consists of a fixed number of threads at startup, and when a new client connection request is made to the server, it will be handed over to a thread in the thread pool, which, after processing the client, returns to the thread pool and continues to wait for the next request. If the connection request arrives at the server, all threads in the thread pool are already occupied, and they wait in a queue until an idle thread is available.

Implementation steps

1. As with a customer thread server, the thread pool server first creates a ServerSocket instance.

2. Then create n threads, each of which loops repeatedly, receiving client connections from the (shared) ServerSocket instance. When multiple threads invoke the Accept () method of a ServerSocket instance at the same time, they will block the wait until a new connection is successfully established, then the system chooses a thread to serve the established connection, and the other threads continue to block the wait.

3. After the thread completes the service to one client, it continues to wait for other connection requests without terminating. If no thread is blocked on the accept () method when a client connection is created (that is, all threads are serving other connections), the system arranges the new connection in one queue until the next time the Accept () method is called.

Sample code

We still achieve http://blog.csdn.net/ns_code/article/details/14105457 this blog function, the client code is the same, the server-side code on its basis to change based on the implementation of thread pool, To facilitate the invocation of the method of handling communication details in an anonymous thread, we made some minor changes to the multithreaded class Serverthread, as follows:

 PackageZyb.org.server;ImportJava.io.BufferedReader;ImportJava.io.InputStreamReader;ImportJava.io.PrintStream;ImportJava.net.Socket;/*** This class is a multithreaded class for service-side*/ Public classServerthreadImplementsRunnable {PrivateSocket client =NULL;  PublicServerthread (Socket client) { This. Client =client; }         //static method for handling communication details, primarily for the convenience of thread pool server invocation     Public Static voidExecute (Socket client) {Try{            //gets the output stream of the socket used to send data to the clientPrintStream out =NewPrintStream (Client.getoutputstream ()); //gets the input stream of the socket, which is used to receive data sent from the client.BufferedReader buf =NewBufferedReader (NewInputStreamReader (Client.getinputstream ())); BooleanFlag =true;  while(flag) {//receive data sent from the clientString str =Buf.readline (); if(str = =NULL|| "". Equals (str)) {Flag=false; }Else{                    if("Bye". Equals (str)) {Flag=false; }Else{                        //The received string is preceded by Echo and sent to the corresponding clientOut.println ("Echo:" +str);            }}} out.close ();            Buf.close ();        Client.close (); }Catch(Exception e) {e.printstacktrace (); }} @Override Public voidRun () {Execute (client); }}

This allows us to easily invoke the method of handling communication details in an anonymous thread, with the improved server-side code as follows:

 PackageZyb.org.server;Importjava.io.IOException;ImportJava.net.ServerSocket;ImportJava.net.Socket;/*** This class implements a thread pool-based server*/ Public classServerpool {Private Static Final intThreadPoolSize = 2;  Public Static voidMain (string[] args)throwsioexception{//server listens for TCP connections to client requests on port 20006        FinalServerSocket Server =NewServerSocket (20006); //There are only threadpoolsize threads in the thread pool,//a maximum of threadpoolsize threads blocking the wait connection request on the Accept () method         for(inti=0;i<threadpoolsize;i++){            //anonymous inner class, the current thread is an anonymous thread and has not yet served any client connectionsThread thread =NewThread () { Public voidrun () {//Loop waits for other connection requests after the thread has serviced a connection                     while(true){                        Try {                            //waiting for the client to connectSocket client =server.accept (); System.out.println ("The connection with the client was successful!" "); //Once the connection is successful, it communicates with the client in that threadserverthread.execute (client); } Catch(IOException e) {e.printstacktrace ();            }                    }                 }            }; //turn on all threads firstThread.Start (); }    }} 
Results analysis

To facilitate testing, in the program, we set the total number of threads in the thread pool to 2, so that the server side can only connect 2 clients, if there are 2 clients connected to the server, when we open the 3rd client, we can no longer establish a connection, the server will not print out the 3rd " Connect with Client successfully! "The words.

This 3rd client will throw a Sockettimeoutexception exception if it has not received the data sent back by the server for a period of time, thus printing out the following information (client code see: http://blog.csdn.net/ns_code/ article/details/14105457):

If a client connection is turned off before the sockettimeoutexception exception is thrown, the 3rd client connects to the server and receives the returned data

Improved

When you create a thread pool, the size of the thread pool is an important consideration, and if you create too many threads (too many idle threads), you consume a lot of system resources, and if you create too few threads, it is still possible for the client to wait a long time to get the service. Therefore, the size of the thread pool needs to be adjusted according to the load, so that the client can connect for the shortest time, ideally there is a scheduling tool that expands the size of the thread pool when the system load increases (below the large upper limit) and reduces the size of the thread pool when the load is reduced. One solution is to use the executor interface in Java.

The executor interface represents an object that executes a runnable instance based on a policy, which may include details such as queueing and scheduling, or how to select the task to perform. The executor interface defines only one method:

Interface executor{

void execute (Runnable task);

}

Java provides a large number of built-in executor interface implementations, all of which can be easily and conveniently used, and the Executorservice interface inherits from the executor interface, which provides a more advanced tool to shut down the server, including normal shutdown and abrupt shutdown. We can get the Executorservice instance by invoking the various static factory methods of the Executors class, and then by calling the Execute () method to assign a thread to the task that needs to be processed, it first tries to use the existing thread, but if necessary, It creates a new thread to handle the task, and if a thread is idle for more than 60 seconds, it moves it to the thread pool, and the task is queued inside the executor instead of being queued in the network system like the previous server, so This strategy is almost always more efficient than the TCP servers implemented in the previous two ways.

The improved code is as follows:

 PackageZyb.org.server;Importjava.io.IOException;ImportJava.net.ServerSocket;ImportJava.net.Socket;ImportJava.util.concurrent.Executor;Importjava.util.concurrent.Executors;/*** This class implements the server through the executor interface*/ Public classServerexecutor { Public Static voidMain (string[] args)throwsioexception{//server listens for TCP connections to client requests on port 20006ServerSocket Server =NewServerSocket (20006); Socket Client=NULL; //Create a Executorservice instance by calling the static method of the Executors class//Executorservice Interface is a sub-interface of the executor interfaceExecutor Service =Executors.newcachedthreadpool (); Booleanf =true;  while(f) {//waiting for the client to connectClient =server.accept (); System.out.println ("The connection with the client was successful!" "); //when the Execute () method is called, a new thread is created to handle the task, if necessary, but it first attempts to use the existing thread.//If a thread is idle for more than 60 seconds, it is removed from the thread pool;//In addition, the task is queued inside the executor, not in the networkService.execute (Newserverthread (client));    } server.close (); }}

Transferred from: http://blog.csdn.net/ns_code/article/details/14451911

Socket server-A TCP server based on the thread pool

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.