public void run() { List<Integer> timedOutSockets = new ArrayList<Integer>(); while (true) { timedOutSockets.clear(); try { lock.readLock(); for (Integer id : socketMap.keySet()) { if (socketMap.get(id).timedOut(timeoutInNs)) { timedOutSockets.add(id); } } lock.readUnlock(); lock.writeLock(); List<Socket> closingSockets = new ArrayList<Socket>(); for (Integer id : timedOutSockets) { SocketWithTimeStamp s = socketMap.remove(id); if (s != null) { log.println(id + " closed because of time out."); closingSockets.add(s.getConnection()); } } lock.writeUnlock(); for (Socket s : closingSockets) { try { s.close(); } catch (IOException e) { // if already closed, just ignore it. } } // some small sleep value so that the garbage collector isn't taking up all the cpu time Thread.sleep(sleepTime); } catch (InterruptedException e) { assert false : "This thread should never be interrupted."; } } }