0

A simple version of my server code can be depicted as...

public class Server implements Runnable {
    static boolean isFirstClient=false;
    ...
    ...
    public void run(){
           ServerSocket ss=new ServerSocket(port);
           while(true){
                  Socket s= ss.accept();
                  if(!isFirstClient){
                        isFirstClient=true;
                        new ClientHandler(s,true);
                  }
                  else{
                       new ClientHandler(s,false);
                  }
           }
    }
    ...
    ...
}

Where client handler handles the client and second parameter in the ClientHandler determines whether its the first client or not and sends the packet accordingly to the client. (I wrote a different functionality for first client to register in the server and response from server determines the first Client.)

public class Client implements Runnable(){
   boolean iamFirst=false;
   public void run(){
          InetAddress ip = InetAddress.getByName("localhost");
          Socket soc = new Socket(ip, port);
          ...
          // response from server is stored in responsePacket.
          ...
          iamFirst=responsePacket.isFirst();
          if(iamFirst){
           ...
           ...
          }
          else{
           ...
           ...
          }
      }
}

But because of large number of clients running at the same time and also use of static variable to detect first client in server it results in running more than 1 client threads as 'firstClient'.

Can anyone suggest the best way to distinguish the first client to register in server keeping in fact that huge number of clients start at the same time?

(Note: I don't want to use sleep() function in the code to seperate one client from other client to simulate a practical scenario.)

Badri
  • 13
  • 1
  • 7

1 Answers1

1

You can make isFirstClient volatile; this makes sure all threads see the latest value of the variable.

Another approach would be to synchronise the method where you accept the clients; but since you do that in a loop it would make no sense in this case.

  • Thanks for answering. Using volatile haven't solved my situation. I tried to keep the question simple, but a lot more goes in actual code of my ClientHandler. I have two types of Client classes(Client1 and Client2). There will be only one instance of Client1 and Multiple instances of Client2. All will start running at the same time. Incase Client1 instance registers first into Server, I have to ignore it. And only the first thread instance of Client2 should be the one to recognized as FirstClient. – Badri Nov 28 '20 at 06:01
  • Because of the code written to ignore instance of Client1, its take time to go to the code where ClientHandler returns packet to Client. By that time other threads have also run the code and some times I am getting no client as first client. Can you suggest some solution for this. – Badri Nov 28 '20 at 06:02
  • I'd create a variable (of type Client1) in Client1 which would store the first client created (so you set it within the constructor). You can also make the construcror (or setter) synchronized on a global object (using the synchronized block, like synchronized(object){code...}), and the constructor would throw an exception if there is already an object stored (the client isn't the first). You can catch that exception and fall back to Client2. –  Nov 28 '20 at 08:05