I am writing a translator, and have quite a few java String literals that are used by the translator. I have my own non-blocking threadsafe tokenizer, which is faster than java.util.regex.Matcher for hard tasks and unlike Matcher class, is immutable so that my tokenizer/Matcher can be shared just like an immutable final class amongst several threads that are doing translation.
The matcher class needs a specialized stringlike class which is like a CharSequence, but tuned to my tokenizer. One subclass of my sequence/stringvariant, which is constructed from a java.lang.String is immutable, and therefore my one translator singleton shared by multiple threads has an interning hashmap that maps String to MyString. I want to intern my immutable string variants which are used in my immutable tokenizer, because many of the literals are the same.
So I have one interning hashmap but unfortunately it is being added to by the static initializers of several other classes, and therefore that sounds like a map which is not threadsafe. How can I incrementally build this interning map without making gets from it block? I also don’t want to use a non-blocking concurrent hashmap. Goal, just a plain HashMap.
Andy
This is a problem, at least in Java 6. According to “Initialization Problems for Java”
So the class init lock is per-class and reliably prevents over-initialization, but two different classes can be initialized concurrently.
I would use a
ConcurrentMapif you’re putting a lot of values into it, or if it might have many readers but few writers, perhaps copy on write inside a mutex and replace since assigning to a field is atomic.