java - 为什么不允许使用 volatile final 字段?

标签 java multithreading concurrency final volatile

我正在设计一个名为 ConcurrentParamters 的线程安全容器类。这是我倾向于写的内容:

接口(interface):

public interface Parameters {
    public <M> M getValue(ParameterMetaData<M> pmd);
    public <M> void put(ParameterMetaData<M> p, M value);
    public int size();
}
public interface ParameterMetaData<ValueType> {
    public String getName();
}

实现:

public final class ConcurrentParameters implements Parameters{

    private final Map<ParameterMetaData<?>, Object> parameters;
    private final volatile AtomicInteger size; //1, Not compile
    {
        size = new AtomicInteger();
        parameters = new ConcurrentHashMap<>();
    }

    public static Parameters emptyParameters(){
        return new ConcurrentParameters();
    }

    @Override
    public <M> M getValue(ParameterMetaData<M> pmd) {
        M value = (M) parameters.get(pmd);
        return value;
    }

    @Override
    public <M> void put(ParameterMetaData<M> p, M value){
        parameters.put(p, value);
        size.incrementAndGet();
    }

    @Override
    public int size() {
        return size.intValue();
    }
}

我试图使表示大小的 AtomicInteger 字段成为最终的,以确保没有方法可以将字段指向另一个对象,并在构造过程中对其进行初始化。

但由于容器将被并发访问,我需要任何线程观察其他线程所做的更改。因此,我也尝试将其声明为volatile,以避免不必要的同步(我不需要互斥)。

我没有编译。为什么?有什么理由吗?以这种方式给一个字段贴花没有意义吗?我认为这是明智的...也许它天生就不安全?

最佳答案

答案很简单:

所有保证 volatile 已经由 final 完成。所以这将是多余的。

查看来自 axtavt 的答案以获取更多详细信息: Java concurrency: is final field (initialized in constructor) thread-safe?

关于java - 为什么不允许使用 volatile final 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33645054/

相关文章:

java - 二叉树搜索小于的值

java - intellij 与 Android SDK : lambda expressions are not supported in -source 1. 7

java - 具有多个订阅者和事件的 RxJava 并发

java - 使用Java ReadWriteLock同步缓存数据——是否将状态变量标记为 volatile ?

c++ - 分析多线程代码,采样如何工作

java - 如何使用 Thread.sleep() 和 setBackground() 在 Swing 中创建闪光效果?

java - 什么是好的嵌入式java应用服务器

Java静态数组修改

关闭线程方法

java - 服务效率