HttpHeaders 源码中headers成员变量为什么声明为final

源码如下

java 复制代码
public class HttpHeaders implements MultiValueMap<String, String>, Serializable {

    private final Map<String, List<String>> headers;

    public String getFirst(String headerName) {
        List<String> headerValues = (List)this.headers.get(headerName);
        return headerValues != null ? (String)headerValues.get(0) : null;
    }

    public void add(String headerName, String headerValue) {
        List<String> headerValues = (List)this.headers.get(headerName);
        if (headerValues == null) {
            headerValues = new LinkedList();
            this.headers.put(headerName, headerValues);
        }

        ((List)headerValues).add(headerValue);
    }

    public void set(String headerName, String headerValue) {
        List<String> headerValues = new LinkedList();
        headerValues.add(headerValue);
        this.headers.put(headerName, headerValues);
    }

猜想

1.为了保证线程安全,可以保证可见性

但是找了一些文档,没有明确表示,可以保证这一点

可实现方案如下:

可见性的技术保障

1、Lock

2、synchronized

3、原子类

4、volatile

Lock和synchronized不用说,都是互斥锁,保障了共享资源在同一时刻只有一个线程可以访问,就不会出现可见性的问题。

volatile保障了一个变量修改以后马上写回主内存让其他线程可以看到,具体的分析后面再说。

至于原子类为什么也有可见性,因为他里面的value本身也是volatile修饰的。

顺便说下有序性

有序性的技术保障

1、synchronized

2、lock

3、volatile(一定程度的有序性)

synchronized和lock在同一时刻只能让一个线程执行同步方法,当然就是有序的了。

volatile的有序性是指写入修改后的volatile变量这个操作必定优先于 读取这个变量。

疑问

final修饰变量不是不可变吗,为什么后续还可以对他进行set add操作

智能搜索答案

分析一下答案,能对的上的

1.提高了性能

2.保证可见性

3.多线程安全

疑问解答

final修饰变量不是不可变吗,为什么后续还可以对他进行set add操作

下面这篇文章说的比较明白

JAVA中final关键字的作用_jvm final 修饰的 在编译阶段-CSDN博客

  • 在上图中, 变量p指向了0003这块内存, 0003内存中保存的是对象p的句柄(存放对象p数据的内存地址), 这个句柄值是不能被修改的, 也就是变量p永远指向p对象. 但是p对象的数据是可以修改的.
  • 不难看出final修饰变量的本质: final修饰的变量会指向一块固定的内存, 这块内存中的值不能改变.
  • 引用类型变量所指向的对象之所以可以修改, 是因为引用变量不是直接指向对象的数据, 而是指向对象的引用的. 所以被final修饰的引用类型变量将永远指向一个固定的对象, 不能被修改; 对象的数据值可以被修改.

几个概念

引用数据类型 VS 基本数据类型

变量的引用(引用变量) (p)

对象的引用(就是内存地址)

对象的数据

内存:内存1:存的是地址;内存2:存的是数据(地址不可改,数据可改)

相关推荐
Uncertainty!!4 分钟前
Linux多用户情况下个别用户输入密码后黑屏
linux·远程连接
necessary65311 分钟前
使用Clion查看linux环境中的PG源码
linux·运维·服务器
江湖有缘1 小时前
Jump个人仪表盘Docker化部署教程:从0到 搭建专属导航页
运维·docker·容器
小猪佩奇TONY2 小时前
Linux 内核学习(14) --- linux x86-32 虚拟地址空间
linux·学习
Lam㊣2 小时前
Centos 7 系统docker:更换镜像源
linux·docker·centos
FL16238631292 小时前
win11+WSL+Ubuntu-xrdp+远程桌面闪退+黑屏闪退解决
linux·运维·ubuntu
石头5302 小时前
Kubernetes监控全栈解决方案:从零搭建Prometheus+Grafana监控体系
linux
ha20428941942 小时前
Linux操作系统学习记录之---TcpSocket
linux·网络·c++·学习
AOwhisky3 小时前
Linux逻辑卷管理:从“固定隔间”到“弹性存储池”的智慧
linux·运维·服务器
翼龙云_cloud3 小时前
阿里云渠道商:如何使用弹性伸缩来实现计算资源的弹性配置?
服务器·阿里云·云计算