Unnecessary synchronization in org.xbill.DNS.Header::getID
See original GitHub issueI’m working on improving the performance of a project that deals with enormous amounts of dns messages. One of the performance bottlenecks I’m seeing is a whole lot of locking in org.xbill.DNS.Header::getID
which is implemented like this:
private static final Random random = new SecureRandom();
public int getID() {
synchronized (random) {
if (id < 0) {
id = random.nextInt(0xffff);
}
return id;
}
}
The implementation is not only synchronized - it’s synchronized around a static
object, meaning that all getID
calls in all Header
instances are serial! Note that SecureRandom
itself is thread-safe and doesn’t require locking.
Could the getID
implementation be changed to be lock-free using a volatile
variable or an AtomicInteger
? Or at least switched to use per-instance locking (e.g. synchronize on this
or some other non-null field) to reduce the lock’s scope?
I’d be happy to submit a PR with a lock-free implementation.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (6 by maintainers)
Top GitHub Comments
It is. I took a glance at the parsing code before submitting the PR.
The
Message
constructors that take abyte[]
orByteBuffer
callHeader(DNSInput in)
, which in turn callsthis(in.readU16());
. So it looks like the parsing flow creates the header with the ID from the wire.Yes, you’re right, I forgot about the DoH http-based caching. I don’t have the project open ATM to search for references, but if parsing the message creates an empty Header instance, we should change that. But I assume that’s already the case.
If the SecureRandom performance really turns out to be an issue I think we can revisit that later.