-
Threads + Sockets
Hey,
I have a number of threads running which create a class that uses a socket to connect to a TCP server. A new instance of the socket connecting to the same IP and Port is created each time a object is created.
Heres how it goes:
- 10 threads are spawned each creating a new instance of my class
- Class creates a new socket (new Socket("host", port))
- The class gets a unique key from the server upon connecting
- The class then uses that unique key to generate a hash
All good up till this point
- I would expect for the thread to send back the hash to the server right away. However, the second thread for some reason creates a new socket and repeats the process above before the 1st thread finished.
- When all 10 threads have finished generating their hash it goes back to the 1st thread which then begins to start sending its hash back to the server. I do not want this to happen, because, well... it invalidates the valid hash it previous generated.
How can I make sure it sends the hash back to the server before any other threads can request one?
I have zero control over the thread creation code.
Thanks,
Tom
-
In general with threaded programming, you can't just "expect" things to happen in a certain order or for one thing to happen before another. If you want things to happen in a certain order, or for one process not to interrupt another, then you need to take steps to enforce this. (Knowing a little about how thread scheduling works, it turns out that the behaviour you mention actually sounds what I'd expect: when one thread is waiting for data from the network, that's exactly one of the moments when the thread scheduler will schedule in another thread; but in any case, you shouldn't rely on this.)
A very simple way in this case (though not necessarily the most elegant or flexible) is just to create some object visible to all the threadas that they will all synchronize on (in a boring old synchronized block) while setting up the hash. So the idea is something like this:
Code:
final Object hashLock = new Object();
...
private void handleConnection(Socket s) {
synchronized (hashLock) {
// get hash for 's'
}
}
A key disadvantage of this approach is that you are creating a bottleneck. Ideally, you should allow the hash creation for one thread to be independent of that of the other thread, or at worst, only synchronize on smallest part of the hash creation code necessary.