I have a server somewhat like this:
class Server {
private WorkingThing worker;
public void init() {
runInNewThread({
// this will take about a minute
worker = new WorkingThing();
});
}
public Response handleRequest(Request req) {
if (worker == null) throw new IllegalStateException("Not inited yet");
return worker.work(req);
}
}
As you can see, there are threads handling requests and a thread initing the server. Requests can come in before initing has finished, therefore there is the check with an IllegalStateException
.
Now, to make this thread safe (so request handler threads don't see a stale, null
-valued, version of worker
just after init), I'd have to make worker volatile, synchronize on it, or some such.
However, after the init has completed, worker
won't ever change again, so it's effectively final. Therefore, it seems like any lock contention that may occur would be a waste. So, what's the most efficient thing I can do here?
Now I know it doesn't really matter in a practical sense (with all the heavy lifting of reading a network request, etc, what does a single lock matter?), but I'd like to know out of curiosity.
A note on volatile: marking a variable volatile is cheaper than using synchronization (it does not involve locks) and is generally cheap enough that you won't notice. In particular, on x86 architectures, reading a volatile variable does not cost more than reading a non-volatile variable. However writing to a volatile is more expensive and the fact that the variable is volatile might prevent some compiler optimisations.
So using volatile is probably the option that gives you the best performance/complexity ratio in your scenario.
You don't have that many alternatives. In the end it boils down to ensuring a safe publication of your worker. And safe publication idioms include:
In your case, only the last two options are available and using volatile is more efficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With