java - 这个命令模式是线程安全的吗?

标签 java multithreading design-patterns

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

最佳答案

这是线程安全的,原因有二。在这种情况下,为了具有纯线程安全性,两者都需要考虑

  1. map 是不可变的(因为它是只读的)。
  2. 它是用类初始化的。 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/

相关文章:

Java: "please wait"GlassPane 未正确加载

Javascript 立即调用函数模式

c++ - 是否有一个对称的设计模式让成员类可以有指向彼此的指针?

ios - 更新 dispatch_sync 队列中的 UI (activityIndi​​cator)( Objective-C )

java - Java 中的 Koblitz 方法

java - 序列化相对简单的 Java POJO 的最快方法?

java - 如何根据特定输入范围读取文件并添加到数组

java - 如果其字段不可变,则外部同步的 ArrayList 线程安全吗?

c# - WCF:如何使用一种方法发送各种类型的消息

java - java中什么时候使用初始化 block ?