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

sexy10Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.