您好 Stackoverflow 社区,
我有一个关于线程安全的问题。如果我有一个静态 Map 并用不同的对象填充它,这些对象是否线程安全,如果我只有方法,它们不会写入其中?
我创建了一个小示例:在这种情况下 getCommand 线程的返回值是否安全?
如何使用 JUnit 测试线程安全?
Controller
public class CommandController {
private static Map<String, Command> commandMap = initMap();
public static Map<String, Command> initMap() {
return new HashMap<String, Command>() {{
put("A", new CommandA());
put("B", new CommandB());
}};
}
public Command getCommand(String key) {
if(commandMap.containsKey(key)) {
return commandMap.get(key);
}
return null;
}
}
抽象类
public abstract class Command {
public abstract int calc(int value);
}
命令A
public class CommandB extends Command {
@Override
public int calc(int value) {
value = value * 4;
return value;
}
}
命令 B
public class CommandA extends Command {
private int ab = 5;
@Override
public int calc(int value) {
return value * ab;
}
}
最佳答案
这是线程安全的,原因有二。在这种情况下,为了具有纯线程安全性,两者都需要考虑
- map 是不可变的(因为它是只读的)。
- 它是用类初始化的。 Since class initialization is thread-safe and guarantees publication, visibility is not an issue.
注意:Slaks 确实提出了一个很好的观点。你应该使用 final。通常,如果您担心线程安全并且该字段既不是最终的也不是易变的,则可能有问题。虽然在这种情况下将其设置为 final 并不能使其更加线程安全,但它只是防止将来发生一些线程不安全的事情(比如重新分配它)。
关于java - 这个命令模式是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19525533/