I, too, don’t think that I fully understand the basis from which you speak, and I candidly suspect that your example might produce a “false positive” since it waits three seconds. Thus, it is probably not a representative example of what might go wrong, since in your example it is unlikely that the threads would ever the threads would never actually conflict with one another.
When you’re dealing with a real-world remote system, the status of that system is only represented by the single stream of messages that the system is sending-out on each of its sockets. I think that, therefore, you need to have one thread on your end which is responsible for knowing the status of every one of them. And, because socket-operations are not terribly fast, a select() loop works perfectly. One thread, processing “one message at a time” from all sources at once, can always keep up and will never present a bottleneck.
This venerable strategy elegantly avoids all timing problems. One thread can easily accommodate all of the connections, and can (centrally) keep track of the status of all of them, so that all of the clients get exactly what they need and want: “Please send this message to somebody, and give me the reply as soon as you get it.” Due to the realities of network-I/O (and, remote systems ...), there’s no reason to make things any more complicated, and, as it were, plenty of reasons not to.