我正在编写一个翻译器,并且有很多翻译器使用的java String文字。我有自己的非阻塞线程安全标记器,它比java.util.regex.Matcher更快,对于硬任务而且与Matcher类不同,它是不可变的,因此我的tokenizer / Matcher可以像几个线程中的不可变最终类一样被共享正在做翻译。
matcher类需要一个类似于字符串的类,它类似于CharSequence,但是调整到我的tokenizer。我的sequence / stringvariant的一个子类是从java.lang.String构造的,是不可变的,因此我的多个线程共享的一个转换器单例有一个将String映射到MyString的实际hashmap。我想实习我的不可变标记器中使用的不可变字符串变体,因为许多文字是相同的。
所以我有一个实习的hashmap但不幸的是它被其他几个类的静态初始化器添加,因此听起来像一个不是线程安全的映射。如何逐步构建此实习地图而不从其中获取阻止?我也不想使用非阻塞并发hashmap。目标,只是一个普通的HashMap。
安迪
答案 0 :(得分:0)
它被几个其他类的静态初始化器添加,
这是一个问题,至少在Java 6中。根据"Initialization Problems for Java"
Java中的并发初始化可能会死锁。如果两个 线程同时初始化两个不同的类 并且两个线程都检测到对另一个类的组件的第一次活动使用,然后两个线程都被阻塞,因为它们都等待相应的 其他线程使其初始化。
因此类init锁是每个类并且可靠地防止过度初始化,但是可以同时初始化两个不同的类。
我会使用ConcurrentMap
如果你把很多值放入其中,或者它可能有很多读者而只有很少的编写者,也许可以在互斥体上写入并复制,因为分配给一个字段是原子。