Enum ValueOf 的 Java 线程安全性

问题描述 投票:0回答:2

关于线程安全,我有一个很可能是愚蠢的问题。我有一个 ENUM 类,我的值定义如下:

public enum ThirdPartyContentSource {
    DEV_TO("DevTo"),
    MEDIUM("Medium"),
    HASH_NODE("HashNode");

    private String thirdPartyText;

    ThirdPartyContentSource(String text) {
        this.thirdPartyText = text;
    }

    public String getText() {
        return this.thirdPartyText;
    }

    public static String valueOfCode(String thirdPartyCode) throws IllegalArgumentException {
        ThirdPartyContentSource text = Arrays.stream(ThirdPartyContentSource.values())
                .filter(val -> val.name().equals(thirdPartyCode))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("Unable to resolve ThirdPartyCode: " + thirdPartyCode));

        return text.getText();
    }
}

我的问题是,如果两个线程同时调用 valueOfCode() 方法,是否存在线程安全问题?

非常感谢

java java.util.concurrent
2个回答
1
投票

不会有任何线程安全问题,因为您没有修改其中的任何数据。不会有竞争条件或类似的东西。


0
投票

tl;博士

thirdPartyText
标记为
final
。那么你是线程安全的。

详情

enum
对象本身(
DEV_TO
MEDIUM
HASH_NODE
)都在其
enum
类加载时实例化。所以那里没有线程安全问题。

您的枚举类带有状态,

thirdPartyText
。该字段的内容是不可变的(
String
)。这很好,因为不可变消除了一些并发问题。

我看到的唯一问题是对象引用是否在运行时发生变化,如果您要用另一个

String
对象替换一个
String
对象。显然,您希望此状态在运行时 not 发生变化。您可以通过将类成员字段声明为
final
来强制执行此操作。成为
final
意味着不能将另一个对象分配给该引用变量。

private final String thirdPartyText;  // Make this field `final`. 

您的

valueOfCode
方法循环遍历枚举(通过
.values
调用),这在运行时不会改变。所以那里没有线程安全问题。

你的

valueOfCode
方法访问我们通过制作
thirdPartyText
修复的
final
字段,所以这些值在运行时不会改变。所以那里没有线程安全问题。

您对

valueOfCode
的意图不明确——请参阅问题上发表的评论。但我在那里没有看到线程安全问题。

虽然我不是并发专家,但在进行

final
更改后,您的代码对我来说看起来是线程安全的。

© www.soinside.com 2019 - 2024. All rights reserved.