0

My main class defines the ExecutorService object with newFixedThreadPool of 3 threads.

public static void main(String[] args) {
    queue = new ArrayBlockingQueue<HashMap<String, String>>(MAX_QUEUE_LENGTH);
    socketThreads = Executors.newFixedThreadPool(3);

    socketThreads.submit(new MyListener(PORT1, queue));
    socketThreads.submit(new MyListener(PORT2, queue));
    socketThreads.submit(new MyListener(PORT3, queue));
}

The Runnables are submitted. Runnables are as follows:

public class MyListener implements Runnable {

  private static ServerSocket listener = null;
  // private Socket socket = null;
  private InputStream inStream = null;
  private OutputStream outStream = null;
  private static ArrayBlockingQueue < HashMap < String, String >> queue = null;

  private static Logger LOGGER = LogManager.getLogger(MyListener.class);
  int port;

  public MyListener(int port, ArrayBlockingQueue < HashMap < String, String >> queue) {
    try {
      listener = new ServerSocket(port);
      this.queue = queue;
      this.port = port;
    } catch (IOException e) {
      LOGGER.fatal("Could not connect to the socket, port number: " + port, e);
    }
  }

  @
  Override
  public void run() {

    do {
      try {
        LOGGER.debug("*** 1 ***");
        Socket socket = listener.accept();
        LOGGER.debug("*** 2 ***");

        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        HashMap < String, String > map = (HashMap < String, String > ) ois.readObject();

        LOGGER.debug("*** 3 ***");
        queue.add(map);

      } catch (IOException e) {
        LOGGER.fatal("Error in socket connection ", e);

      } catch (ClassNotFoundException e) {
        LOGGER.fatal("Error - Class not found ", e);

      } catch (ClassCastException e) {
        LOGGER.fatal("Error - Class Cast Exception ", e);
      }
    } while (true);
  }
}

So, basically the socket reads an incoming data and adds that to the queue. The idea is that once the request comes in and is obtained, the socket should again start waiting for the connection. My code works when I have a single thread pool running but doesn't work if I start > 1 threads in the pool. As you can see in the code, the execution reaches log statement * * * 1 * * * and the accept never happens.

I tried to separate out the ObjectnputStream from this and run it a separate runnable, but that does not help either after reading Creating a socket server which allows multiple connections via threads and Java. Any reason why this happens?

Community
  • 1
  • 1
Madz
  • 199
  • 5
  • 18
  • Could you add the code from your main class which schedules the MyListener? Also, the post you linked to advices to call accept() on the main thread and use separate threads (via the ExecutorService in your case) only for processing the accepted socket. Perhaps you could try this? – Michael Koch Nov 04 '15 at 19:49
  • The problem is that I need the thread to listen to the port continuously and update the queue. Hence I cannot really use the solution in that link. – Madz Nov 04 '15 at 20:01
  • That's no problem. The ServerSocket listens to connections even while you're not in an accept() call. accept() will return immediately if there is already a connection. The queue size for incoming un-accepted connections is a constructor argument (see http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#ServerSocket(int,%20int)). – Michael Koch Nov 04 '15 at 20:06
  • `LOGGER.debug("*** 1 ***");` is never ran? – MeetTitan Nov 04 '15 at 20:46
  • Only that runs, I can see that but accept is not called. – Madz Nov 04 '15 at 20:47
  • Try `socket.close()` after `queue.add(map)`, to make sure we don't have a hanging socket making our subsequent `accept()` call potentially hang. – MeetTitan Nov 04 '15 at 21:07
  • Hmm, but that is when it reiterates, it doesn't go any further than accept in the first iteration itself. But your suggestion has a very good point. – Madz Nov 04 '15 at 21:09

1 Answers1

1
  1. The ServerSocket should not be static. You're overwriting it every time you create a new listener object.

  2. Everything to do with an accepted client is in the wrong place: its socket and both its streams. These should be non-static members of another Runnable class that is instantiated to handle each accepted socket.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • can you also say what causes this problem? @EJP – Madz Nov 05 '15 at 10:07
  • @Madz, he means remove the static keyword from `listener` and `queue`. Because static variables belong to the class, and not the instance of the class. Good catch EJP, I overlooked his declarations. – MeetTitan Nov 06 '15 at 11:14
  • @Madz I *have* said what causes this problem. What do you mean by 'also'? – user207421 Nov 06 '15 at 23:20