• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 847
  • Last Modified:

How to add an array list to a multithreaded server application

The multithreaded server needs to include and arrayList to store clients threads.   Im not quite sure were to add the arrayList code:
while(true)
arrayListOfRunnables.add(new runnable);

   for(int i = 0; i < arrayListOfRunnables.size(); i++)
   
       arrayListOfRunnables.get(i).start()
   
// Fig. 24.5: MTServer.java
 
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.awt.BorderLayout;
/*import java.awt.event.ActionEvent;*/
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
 
 
 
public class MTServer extends JFrame
{
   private JTextField enterField;
   private JTextArea displayArea;
   private ObjectOutputStream output;
   private ObjectInputStream input;
   private ServerSocket server;
   private Socket connection;
   private int counter = 1;
   private ArrayList runnableClients = new ArrayList();
 
   // set up GUI
   public MTServer()
   {
      super( "Server" );
      enterField = new JTextField();
      enterField.setEditable( false );
 
      /*enterField.addActionListener(
         new ActionListener()
         {
            // send message to client
            public void actionPerformed( ActionEvent event )
            {
               //serverLock.lock();
               sendData( event.getActionCommand() );
               enterField.setText( "" );
            }
         }
      ); // end ActionListener */
      
 
      add( enterField, BorderLayout.NORTH );
 
      displayArea = new JTextArea();
      add( new JScrollPane( displayArea ), BorderLayout.CENTER );
 
      setSize( 300, 150 );
      setVisible( true );
   } // end Server constructor
 
   // set up and run server
 
public void runServer()
{
 
	try
	{
		server = new ServerSocket(20000, 100);
 
		while(true)
		{
			connection = server.accept();
 
		    displayMessage( "Connection " + counter + " received from: " +
           				connection.getInetAddress().getHostName());
 
			runnableClients.add(new ClientConnection(connection, counter));
 
			int numOfClients = runnableClients.size();
 
	    	  System.out.println("the number of client threads stored is " + numOfClients + "\n");
 
	    	  for(int i = 0; i < numOfClients; i++)
	    	  {
			  	(new Thread( (ClientConnection) runnableClients.get(i) )).start();
			  }
			  counter++;
		}//end while
	}
	catch(IOException iox)
	{
	 	System.err.println("IOException in runServer");
		 iox.printStackTrace();
	}
	catch(Exception x)
	{
		System.err.println("Error in runServer()");
		x.printStackTrace();
	}
}//end runServer
 
 
 
 
/**  ClientConnecrtion run  **********************************************************************************/
 
   private class ClientConnection implements Runnable
   {
 
      private Socket sockClientConn = new Socket();
      private int clientNum;
      private ObjectOutputStream clientConnOut;
      private ObjectInputStream clientConnIn;
 
      public ClientConnection(Socket s, int cNum)
      {
		  sockClientConn = s;
		  clientNum = clientNum;
          try
          {
			  clientConnOut = new ObjectOutputStream(sockClientConn.getOutputStream());
			  clientConnOut.flush();
		  }
		  catch(IOException iox)
		  {
			  iox.printStackTrace();
		  }
 
	  }
 
	public void run()
      {
 
		System.out.println("new client thread running.");
 
		try
      	{
 
            try
            {
            	clientConnIn = new ObjectInputStream(sockClientConn.getInputStream());
            	processConnection();
            }
            catch ( EOFException eofException )
            {
               displayMessage( "\nServer terminated connection" );
            }
            finally
            {
               closeConnection();
               counter++;
          	}
 
      }
      catch ( IOException ioException )
      {
         ioException.printStackTrace();
      }
   } //end run
 
/** processConnection  *********************************************************************/
 
  private void processConnection() throws IOException, EOFException
     {
        System.out.println("entered processConnection");
        String message = "Connection successful";
        sendData( message );
 
 
        setTextFieldEditable( true );
 
  	  do
  		   {
  			   try{
  				   message = (String) clientConnIn.readObject();
  				  }
  				  catch(IOException iox)
  				  {
  					  iox.printStackTrace(System.err);
  					  System.err.println("An Error has occured client handler run()");
  				  }
  				  catch(Exception x)
  				  {
  					  System.err.println("ERROR");
  				  }
  		   }while(!message.equals("SERVER>>> TERMINATE"));
 
  		    System.out.println("leaving process connection\n");
 
 
     } // end method processConnection
 
//** close connections ****************************************************************/
 
 
	    private void closeConnection()
	    {
	       displayMessage( "\nTerminating connection\n" );
	       setTextFieldEditable( false );
 
	       try
	       {
	          clientConnOut.close();
	          clientConnIn.close();
	          connection.close();
	       }
	       catch ( IOException ioException )
	       {
	          System.err.println("Error closing connection.");
	          ioException.printStackTrace();
	       }
	    } // end method closeConnection
 
	    // send message to client
/** sendData  **************************************************************************/
 
		private void sendData( String message )
			    {
			       try // send object to client
			       {
			          clientConnOut.writeObject( "SERVER>>> " + message );
			          clientConnOut.flush();
			          displayMessage( "\nSERVER>>> " + message );
			       }
			       catch ( IOException ioException )
			       {
			          displayArea.append( "\nError writing object" );
			       }
			    } // end method sendData
  }//end clientConnection
 
private void displayMessage( final String messageToDisplay )
   {
      SwingUtilities.invokeLater(
         new Runnable()
         {
            public void run() // updates displayArea
            {
               displayArea.append( messageToDisplay );
            } // end method run
         } // end anonymous inner class
      ); // end call to SwingUtilities.invokeLater
   } // end method displayMessage
 
   // manipulates enterField in the event-dispatch thread
   private void setTextFieldEditable( final boolean editable )
   {
      SwingUtilities.invokeLater(
         new Runnable()
         {
            public void run() // sets enterField's editability
            {
               enterField.setEditable( editable );
            }
         }
      );
   }
 
 
}//end MTServer
 
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
 
public class Client extends JFrame
{
   private JTextField enterField; 
   private JTextArea displayArea; 
   private ObjectOutputStream output; 
   private ObjectInputStream input; 
   private String message = ""; 
   private String chatServer; 
   private Socket client; 
 
   public Client( String host )
   {
      super( "Client" );
 
      chatServer = host; // set server to which this client connects
 
      enterField = new JTextField(); // create enterField
      enterField.setEditable( false );
      enterField.addActionListener(
         new ActionListener()
         {
            // send message to server
            public void actionPerformed( ActionEvent event )
            {
               sendData( event.getActionCommand() );
               enterField.setText( "" );
            } // end method actionPerformed
         } // end anonymous inner class
      ); // end call to addActionListener
 
      add( enterField, BorderLayout.NORTH );
 
      displayArea = new JTextArea(); 
      add( new JScrollPane( displayArea ), BorderLayout.CENTER );
 
      setSize( 300, 150 ); 
      setVisible( true ); 
   } // end Client constructor
 
   // connect to server and process messages from server
   public void runClient()
   {
      try // connect to server, get streams, process connection
      {
         connectToServer(); // create a Socket to make connection
         getStreams(); // get the input and output streams
         processConnection(); // process connection
      } // end try
      catch ( EOFException eofException )
      {
         displayMessage( "\nClient terminated connection" );
      } // end catch
      catch ( IOException ioException )
      {
         System.err.println("\nIO Exception");
         ioException.printStackTrace();
      } // end catch
      finally
      {
         closeConnection();
      } //
   } // end method runClient
 
   // connect to server
   private void connectToServer() throws IOException
   {
      displayMessage( "Attempting connection\n" );
 
      // create Socket to make connection to server
      client = new Socket( InetAddress.getByName( chatServer ), 20000 );
 
 
      displayMessage( "Connected to: " +
         client.getInetAddress().getHostName() );
   } // end method connectToServer
 
   // get streams to send and receive data
   private void getStreams() throws IOException
   {
      // set up output stream for objects
      output = new ObjectOutputStream( client.getOutputStream() );
      output.flush(); // flush output buffer to send header information
 
      // set up input stream for objects
      input = new ObjectInputStream( client.getInputStream() );
 
      displayMessage( "\nGot I/O streams\n" );
   } // end method getStreams
 
   // process connection with server
   private void processConnection() throws IOException
   {
      // enable enterField so client user can send messages
      setTextFieldEditable( true );
 
      do
      {
         try
         {
            message = ( String ) input.readObject();
            displayMessage( "\n" + message );
         }
         catch ( ClassNotFoundException classNotFoundException )
         {
            displayMessage( "\nUnknown object type received" );
         }
         catch(Exception x)
         {
			 x.printStackTrace(System.err);
		 }
 
      } while ( !message.equals( "SERVER>>> TERMINATE" ) );
   } // end method processConnection
 
   // close streams and socket
   private void closeConnection()
   {
      displayMessage( "\nClosing connection" );
      setTextFieldEditable( false );
      try
      {
         output.close(); // close output stream
         input.close(); // close input stream
         client.close(); // close socket
      }
      catch ( IOException ioException )
      {
         ioException.printStackTrace();
      }
   } // end method closeConnection
 
   // send message to server
 
/** sendData  *******************************************************************************/
 
private void sendData( String message )
   {
      try
      {
         output.writeObject( "CLIENT>>> " + message );
         output.flush(); // flush data to output
         displayMessage( "\nCLIENT>>> " + message );
      }
      catch ( IOException ioException )
      {
         displayArea.append( "\nError writing object" );
      }
   } // end method sendData
 
   // manipulates displayArea in the event-dispatch thread
 
   /** displayMessage  ***********************************************************************/
 
   private void displayMessage( final String messageToDisplay )
   {
      SwingUtilities.invokeLater(
         new Runnable()
         {
            public void run() // updates displayArea
            {
               displayArea.append( messageToDisplay );
            }
         }
      ); // end call to SwingUtilities.invokeLater
   } // end method displayMessage
 
   // manipulates enterField in the event-dispatch thread
   private void setTextFieldEditable( final boolean editable )
   {
      SwingUtilities.invokeLater(
         new Runnable()
         {
            public void run()
            {
               enterField.setEditable( editable );
            }
         }
      ); // end call to SwingUtilities.invokeLater
   }
} // end class Client
 
 
import javax.swing.JFrame;
 
public class MTServerTest
{
 
   public static void main( String args[] )
   {
      MTServer application = new MTServer(); // create server
      application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      application.runServer();
      // run server application
   } // end main
} // end class ServerTest
 
 
import javax.swing.JFrame;
 
public class ClientTest 
{
   public static void main( String args[] )
   {
      Client application; // declare client application
 
      // if no command line args
      if ( args.length == 0 )
         application = new Client( "127.0.0.1" ); // connect to localhost
      else
         application = new Client( args[ 0 ] ); // use args to connect
 
      application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      application.runClient(); // run client application
      {

Open in new window

0
sexy10
Asked:
sexy10
2 Solutions
 
AjarCommented:
May be you want to not do the dirty work of thread management but instead use the  Java concurrent Executor and Future Task for it.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executor.html
0
 
rbrindlCommented:
This is a similar problem i had some time ago when i wrote a testcase that tested a piece of code that should run multithreaded.
As Ajar mentioned, i used the executor for it because it abstracts all the threading stuff away in quite a beautiful way.
See Code Snippet.
List<Callable<Object>> clist = new ArrayList<Callable<Object>>();
for(int i = 0; i < threadCount ; i++)
{
   Callable<Object> callable = new Callable<Object>() {
      public Object call() throws Exception 
      {
             //do something
             return result;
      }
   };
   clist.add(callable);
}
 
List<Future<Object>> futures=executor.invokeAll(clist);
 
for (Future<Object> future : futures) 
{
    future.get();
}

Open in new window

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now