William Pugh reports that FindBugs flags the following code from RelationService:
private Long myNtfSeqNbrCounter = new Long(0);
...
private Long getNotificationSequenceNumber() {
Long result = null;
synchronized(myNtfSeqNbrCounter) {
result = new Long(myNtfSeqNbrCounter.longValue() + 1);
myNtfSeqNbrCounter = new Long(result.longValue());
}
return result;
}
This is a well-known bug pattern. If two threads arrive at the synchronized block at the same time then they will both synchronize on the same Long object. Whichever of them gets the lock on it first will then update myNtfSeqNbrCounter with a new Long object, but the Java Memory Model does not guarantee that the other one will then see the updated field when it calls myNtfSeqNbrCounter.longValue().