Memorandum of Rookie Java Java (Nine)

zhaozj2021-02-16  47

Saturday, January 25, 2003

I suddenly discovered the use of the interface to implement multi-threading and utilizing the construction lines. I didn't seem too much attention. When using the class constructor, you need to use this class to define thread objects, such as mythread thread1 = New mythread (), while using the interface to create a line, you only need to use the Thread class, such as Thread Thread1 = New Thread (Mythread). This is reflected in the multi-threaded sockets mentioned in a few days ago. .

The previous unremitting efforts allow me to continue the original unfinished job now, officially advancement to the connected pool version of Socket.

Review how we created multi-threaded server MultithreadremoteFileServer, this is to see the contents of the previous day. Summary, it is to use a thread for each Waiting Connected customer New. Whenever a client Create a new ConnectionHandler in a new THREAD when applying for a connection. This means that there may be a THREAD running throughout the system. Obviously, the system's overhead will be due to the number of connecting customers The growth rate is increasing. We can't take into account the increase in overhead to a certain extent, the system will not be able to afford the possibility. Therefore, we have to restrict the number of ways to connect customers and improve the efficiency of the server.

The So solution is: On the server side, we created a certain number of PooledConnectionHandler when you start, let's put your access connections into a connection pool and make the PooledConnectionHandler to take the remaining things. The client's program does not have to be modified, so The advantages of the design are as follows:

1. Limit the number of allowed to connect at the same time. 2. I only need to start the PooledConnectionHandler thread limited time

The meaning of these two sentences will be reflected in the subsequent program, the following is the structure of the PooledRemoteFileServer class:

Import java.io. *; import java.ut. *; import java.util. *;

Public Class PooledRemoteFileServer {protected int maxconnections; // Defines the maximum number of client connections that can handle simultaneously protected int Listenport; // Defines the port number to listen to Protected Servetsocket Serversocket;

public PooledRemoteFileServer (int aListenPort, int maxConnections) {listenPort = aListenPort; this.maxConnections = maxConnections;} public static void main (String [] args) {} public void setUpHandlers () {// create a number of maxConnections PooledConnectionHandler} public void Acceptconnections () {// In the ServerSocket, the incoming client is listened, and the previous RemoteFile Server, the listener in MultithreadRemoteFileServer is exactly the same} Protected Void HandleConnection (Socket IncomingConnection) {} // Connection Processor}

Similarly, first look at the main function public static void main (String [] args) {PooledRemoteFileServer Server = New PooledRemoteFileServer (3000, 3); server.setupHandlers (); // We must create the main function of all servers in front A connecting pool, there are three available connectionhandler server.acceptconnections (); // Once ready, start listening to what we will see how we will create three ConnectionHandler how to implement:

public void setUpHandlers () {for (int i = 0; i

SetupHandlers () Method Creates MaxConnections and activates them in New Thread. PooledConnectionHandler is here a thread body implemented with an interface (Runnable). Create thread to create thread to call Start () in Thread () and Run () can be desired to be called on Runnable. That is, our PooledConnectionHandler will wait for the accessible connection, each in its own thread. We only create three Threads in the example, and once the server is running, this cannot be changed.

Acceptconnections () method is slightly not written, see the connection handler HandleConnection (socket incomingconnection)

Protected Void HandleConnection (socket connectiontohandle) {PooledConnectionHandler.ProcessRequest (ConnectiontoHandle);

Here, the connection handler directly calls the PooledConnectionHandler thread class method ProcessRequest to process the listening connection, apparently this ProcessRequest is a static method.

The methods in the PooledRemoteFileServer class involve an important thread class, PooledConnectionHandler. Let's take a look at the length of such an interface:

public class PooledConnectionHandler implements Runnable {protected Socket connection; // currently being processed on behalf Socket protected static List pool = new LinkedList (); // static connections need to save LinkedList called pool being processed, is used to simulate a LinkedList Connection pool PUBLIC POOLEDCONNECTIONHANDLER () {// Constructor} public void handleconnection () {// Connected I / O operation here} public static void processRequest (socket requesttohandle) {// Handling customer connection, join them to connect Pool} public void run () {// Waiting for connection, come, adjust the handleconnection () process}}

It can be seen that this class is very similar to the ConnectionHandler of Multithreaded Socket. However, it has a means of processing the connection pool. First see the processRequest () method to use in the listener program Public Static Void ProcessRequest (Socket RequesttoHandle) {Synchronized (pool) {pool.add (pool.size (), requesttohandle; pool.notifyall ();}}

The RequestToHandle here is the client to be processed to connect socket. It can be said that the work made by ProcessRequest is to join the client connection to the connection pool. But make sure there is no other thread interference when operating the connection pool (POOL), Just get the object lock of the connection pool, and use the synchronization block, you know the concept about Synchronized, you can send it here.

So, since we have guaranteed that we are the only "Wanting", we can add incoming sockets to the end of LinkedList. Once we add new connections, we can use pool.notifyall to inform others waiting The THREAD of the pool, the object lock of the connection pool is released now. From another perspective, it can also be said to notify another thread that is waiting for, some of the conditions have been there.

So what is this thread waiting for?

Let's implement the Run () method on the PooledConnectionHandler, which will wait on the connection pool, and a connection in the pool handles it, so this is waiting for this thread to handle the connection:

Public void Run () {while {Synchronized (pool) {while (pool.isempty ()) {Try {pool.wait ();} catch (interruptedException e) {return;}} connection = (socket) pool .remove (0); // snap the first connection in the pool, make it a connection} handleconnection (); // then handed over the Handleconnection processing}}

This function tells us what every PooledConnectionHandler thread is in Run. Obviously, it is going to see if there is any access in the connection pool, if there is, it is handled, so it is waiting "connection pool Connected "This condition is to tell it that this condition is satisfied, it is obviously the processRequest. When the processRequest issued a notice (pool.notify ()), this condition is satisfied, then in Run () If the handler is not waiting, you can immediately go out to handle it. In turn, WAIT () is still in a blocking state before this condition is not satisfied, or stagnation state. It is also necessary to operate the Pool, so the synchronization block is also required here.

Let's review the concept of the object lock again. How can processRequest () in the pool when run () has a pool's mutex lock? The answer is to release the call release lock on Wait () on the pool, and wait () will then take the lock again before returning. This allows the other synchronization code of the pool object to get the lock.

Finally, let's take a look at the HandleConnection () method in the PooledConnectionHandler thread. Follow the multi-threaded server, our PooledConnectionHandler has a HandleConnection () method. The code of this method is exactly the same as the code of the Run () method on the ConnectionHandler in the multi-threaded server. First, we package OutputStream and InputStream, package into (GetOutputStream () and GetInputStream ()) BUFFEREDReader and PrintWriter on the GetOutputStream () and GetInputStream ()). Then we read the target file by line, just like we do in the multi-threaded example. Three another time, we will put them in the local line variable after some bytes and then write it to the client. After completing the read and write operation, we turn off the FileReader and the open stream. Tell this, we can see that there are two classes in the program, and PooledRemoteFileServer and PooledConnectionHandler.PooledRemoteFileServer do not directly process the connection request, it is just responsible for listening to these connections, and puts them in the connection pool, as for the specific link of the processing, It is responsible for the PooledConnectionHandler.

Our servers with connecting pools are completed. Let's review the steps to create and use the "Pool Edition" server:

1. Create a new type of connection handler (we call PooledConnectionHandler) to handle connections in the pool. 2. Modify the server to create and use a set of PooledConnectionHandler.

Attached: PooledRemoteFileServer.java source code

Import java.io. *; import java.ut. *; import java.util. *;

public class PooledRemoteFileServer {protected int maxConnections; protected int listenPort; protected ServerSocket serverSocket; public PooledRemoteFileServer (int aListenPort, int maxConnections) {listenPort = aListenPort; this.maxConnections = maxConnections;} public void acceptConnections () {try {ServerSocket server = new ServerSocket (listenPort, 5); Socket incomingConnection = null; while (true) {incomingConnection = server.accept (); handleConnection (incomingConnection);}} catch (BindException e) {System.out.println ( "Unable to bind to port" listenPort);} catch (IOException e) {System.out.println ( "Unable to instantiate a ServerSocket on port:" listenPort);}} protected void handleConnection (Socket connectionToHandle) {PooledConnectionHandler.processRequest (connectionToHandle);} public Static void main (String [] args) {PooledRemoteFileServer server = new PooledRemoteFileServer (3000, 3); server.setUpHandlers (); server.acceptConnections ();} public void setUpHandlers () {for (int i = 0; i

class PooledConnectionHandler implements Runnable {protected Socket connection; protected static List pool = new LinkedList (); public PooledConnectionHandler () {} public void handleConnection () {try {PrintWriter streamWriter = new PrintWriter (connection.getOutputStream ()); BufferedReader streamReader = new BufferedReader (new InputStreamReader (connection.getInputStream ())); String fileToRead = streamReader.readLine (); BufferedReader fileReader = new BufferedReader (new FileReader (fileToRead));

String line = null; while ((line = fileReader.readline ())! = Null) streamwriter.println (line);

FileReader.close (); streamwriter.close (); streamreader.close ();} catch (filenotfoundexception e) {system.out.println ("COULD NOT FIND Requested File on The Server.");} catch (IOException E) {System.out.println ( "Error handling a client:" e);}} public static void processRequest (Socket requestToHandle) {synchronized (pool) {pool.add (pool.size (), requestToHandle); pool.notifyAll ();}} Public void run () {while {synchronized (pool) {while (pool) {Try {pool.wait ();} catch (interruptedException e) {return;}} = (Socket) pool.remove (0);} Handleconnection ();}}}

转载请注明原文地址:https://www.9cbs.com/read-27536.html

New Post(0)