gpt4 book ai didi

java - 测试线程安全单例的代码中的奇怪行为

转载 作者:搜寻专家 更新时间:2023-11-01 01:04:48 24 4
gpt4 key购买 nike

我对 Java 中的多线程相当陌生。因为我需要一个线程安全的单例(我将其实现为枚举),所以我编写了一个小的测试代码,它产生了一个奇怪的输出。

代码:

public enum EnumSingleton {
INSTANCE;


/** state variables */
private String message;

/** Constructor */
private EnumSingleton() {
}

/** add well-known accessor for the instance (is NOT necessary) */
public static EnumSingleton getInstance() {
return INSTANCE;
}


/** Accessors */
public String getMessage() {
return message;
}

public void setMessage(String name) {
this.message = name;
}
}

public class App {

public static void main(String[] args) {

for (int i = 0; i < 10; i++) {
final int b = i;
Thread thread = new Thread("Thread #" + b) {
@Override
public void run() {
EnumSingleton singleton = EnumSingleton.getInstance();
singleton.setMessage("Message written by "+this.getName());
System.out.println("Current thread "+this.getName() + ": "+singleton.getMessage());
}
};
thread.start();
}
}
}

因此每个线程都将其名称写入枚举的属性“message”中,然后将其打印到 STDOUT。我得到以下我觉得很奇怪的输出:

Current thread Thread #6: Message written by Thread #3
Current thread Thread #1: Message written by Thread #1
Current thread Thread #8: Message written by Thread #8
Current thread Thread #5: Message written by Thread #1
Current thread Thread #4: Message written by Thread #4
Current thread Thread #9: Message written by Thread #9
Current thread Thread #7: Message written by Thread #3
Current thread Thread #2: Message written by Thread #3
Current thread Thread #0: Message written by Thread #3
Current thread Thread #3: Message written by Thread #3

我期望的是我为每个循环计数器 (0-9) 得到一条消息。但是在这个例子中,我有多个线程 #3 写的消息,怎么可能呢?是否存在竞争条件?

如果我的代码很糟糕:如何正确测试单例的线程安全性?

最佳答案

这里有一个明显的竞争条件,因为枚举的单例实例中有一个变量 message。您的线程都在同时写入和读取该变量,因此您会期望看到这样的结果。

枚举构造意味着您的单例对象的创建是线程安全的,但是仍然需要正确处理对其中方法的调用。

做你正在寻找的方法是让 message 成为 thread local变量或将消息的设置和消息的读取放在单个 synchronized block 中,可能锁定在单例对象上。

关于java - 测试线程安全单例的代码中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34068864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com