I'm studying ChronicleHFT libraries. I found a class StringInterner
posted below
public class StringInterner {
@NotNull
protected final String[] interner;
protected final int mask;
protected final int shift;
protected boolean toggle = false;
public StringInterner(int capacity) throws IllegalArgumentException {
int n = Maths.nextPower2(capacity, 128);
this.shift = Maths.intLog2((long)n);
this.interner = new String[n];
this.mask = n - 1;
}
@Nullable
public String intern(@Nullable CharSequence cs) {
if (cs == null) {
return null;
} else if (cs.length() > this.interner.length) {
return cs.toString();
} else {
int hash = Maths.hash32(cs);
int h = hash & this.mask;
String s = this.interner[h];
if (StringUtils.isEqual(cs, s)) {
return s;
} else {
int h2 = hash >> this.shift & this.mask;
String s2 = this.interner[h2];
if (StringUtils.isEqual(cs, s2)) {
return s2;
} else {
String s3 = cs.toString();
this.interner[s != null && (s2 == null || !this.toggle()) ? h2 : h] = s3;
return s3;
}
}
I found yt video from Peter Lawrey on which he explains (or to be more precise - he just says) that this class is thread safe and doesn't need any additional synchronization to work in multithreaded environment. Video yt link: https://www.youtube.com/watch?v=sNSD6AUG5a0&t=1200
My question is why this class doesn't need any sync?
- How about visibility - if one thread put something into interner[n], does another threads are guaranteed to see it?
- What happens in case, when scheduler yields a thread in the middle of method? Does it lead to put same value in same index twice?