java - 字符串数组 - 不必要的同步?

标签 java multithreading chronicle

我正在研究 ChronicleHFT 库。我发现下面发布了一个类 StringInterner

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;
                }
            }
   

我找到了 Peter Lawrey 的视频,他在视频中解释(或者更准确地说 - 他只是说)该类是线程安全的,不需要任何额外的同步即可在多线程环境中工作。视频链接:https://www.youtube.com/watch?v=sNSD6AUG5a0&t=1200

我的问题是为什么这个类不需要任何同步?

  1. 可见性如何 - 如果一个线程将某些内容放入 interner[n] 中,其他线程是否一定能看到它?
  2. 当调度程序在方法中间产生一个线程时,会发生什么情况?这是否会导致将相同的值放入同一索引两次?

最佳答案

Javadoc for StringInterner解释说它在技术上不是线程安全的:

StringInterner only guarantees it will behave in a correct manner. When you ask it for a String for a given input, it must return a String which matches the toString() of that CharSequence.

It doesn't guarantee that all threads see the same data, nor that multiple threads will return the same String object for the same string. It is designed to be a best-effort basis so it can be as lightweight as possible.

So while technically not thread safe, it doesn't prevent it operating correctly when used from multiple threads, but it is faster than added explicit locking or thread safety. NOTE: It does rely on String being thread safe, something which was guarenteed from Java 5.0 onwards.

顺便说一句,我对 Java 5 之前的 String 不是线程安全的说法很好奇;我很想看到引用。

关于java - 字符串数组 - 不必要的同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63383745/

相关文章:

java - Android studio crossfade drawables 崩溃应用程序

java - 如何转义java中正则表达式模式中的特殊字符?

swift - MVVM Realm : Passing Realm-results across threads?

java - 围绕变量而不是类或方法进行同步

java - ChronicleMap 条目的最大数量

java - 在两个 JVM 之间快速传递图像数据

java - Java 中的 repaint() 方法是否需要计时器或操作?

java - 如何从一台机器针对另一台机器运行ant脚本?

c++ - 如何在主进程和线程之间使用 Unix 管道?

performance - 编年史队列硬断电恢复