共享内存之不可变

news/2024/5/20 9:11:29 标签: java, 开发语言, JUC, JVM, 内存

目录

一、不可变设计

二、享元模式

三、final原理


一、不可变设计

String是怎么保证不可变的?

首先String类里面有个char数组value,是用final修饰的,所以只有在构造的时候能给他赋值,以后就没机会改变他的引用了。

有个变量hash,用来缓存字符串的哈希码,只有首次调用字符串时才会生成,后面就缓存再变量里避免后面计算,私有的没set方法所以没办法改变。

类上也加了final修饰保证了该类中的方法不能被覆盖,防止系列无意间破坏不可变性

java">public final class String
     implements java.io.Serializable, Comparable<String>, CharSequence {
     /** The value is used for character storage. */
     private final char value[];

     /** Cache the hash code for the string */
     private int hash; // Default to 0
 
     // ...
}

final只能保证引用不变,他是怎么保证里面的数据不改变的呢?

看下面代码可见他的构造器是采用复制的方式来构建一个的,防止别的地方改了这个引用对象的值从而改了String(这种思想叫:保护性拷贝

java">public String(@NotNull String original){
    this.value = original.value;
    this.hash = original.hash;
}

public String(@NotNull char value[]){
    this.value = Arrays.copyOf(value,value.length);
}

可见在substring的源码也是如此,他返回的时候也是new了个新的来返回,这样substring并没有改动原来的字符串对象

java">public String substring(int beginIndex) {
     if (beginIndex < 0) {
         throw new StringIndexOutOfBoundsException(beginIndex);
     }
     int subLen = value.length - beginIndex;
     if (subLen < 0) {
         throw new StringIndexOutOfBoundsException(subLen);
     }
     return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

public String(char value[], int offset, int count) {
     if (offset < 0) {
         throw new StringIndexOutOfBoundsException(offset);
     }
     if (count <= 0) {
         if (count < 0) {
             throw new StringIndexOutOfBoundsException(count);
         }
         if (offset <= value.length) {
             this.value = "".value;
             return;
         }
     }
     if (offset > value.length - count) {
         throw new StringIndexOutOfBoundsException(offset + count);
     }
     this.value = Arrays.copyOfRange(value, offset, offset+count);
}

这种通过创建副本对象来避免共享的手段称之为保护性拷贝

二、享元模式

由于保护性拷贝每次都会复制对象,就可以用享元模式来解决,他是23种设计模式之一,用在当需要重用数量右下的同一类对象时

JDK中Boolean、Byte、Short、Long、Integer、Character等包装提供了valueOf方法,例如Long的valueOf会缓存-128-127之间的Long对象,在这个范围之间会重用对象,大于这个范围才会新建Long对象

java">public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

是怎么实现这个缓存的呢? 他有个静态内部类LongCache初始化会创建大小为256的数组,然后初始化代码块会事先给他们赋值,之后调用valueOf直接从数组里获取,避免对象的重复创建

注意:Byte、Short、Long的缓存范围都是-128-127,Character缓存的是0-127,Integer的默认是-128-127最小的是不能变,但是这个127是可以调整参数Djava.lang.Integer.integerCache.high来改变。Boolean缓存了true和false

三、final原理

final的设置变量的原理,如果一个成员变量别标识为final,那么他在赋值的时候会加入写屏障,他可以保证写屏障之前的都不会重排序到写屏障之后

获取final变量的原理:如果final的变量是享元缓存范围内的会直接去栈内存中拿,如果是享元缓存外的会去常量池里面拿,如果不在final修饰,他都是在堆中拿


http://www.niftyadmin.cn/n/458633.html

相关文章

前端3D Three.js 在本地搭建一个官方网站

上文Web前端 3D开发入门规划 3D效果将不再是桌面应用的专利我们说了说 WEB 3D的一个发展和学习方向 那么 我们还是先搞定文档使用的问题 我们可以访问http://www.yanhuangxueyuan.com/Three.js/这里面可以查到使用方法 但不是最新的 而是别人用官方文档改的 真正的官方文档地址…

plt保存图像

plt.figure() plt.plot(img) plt.show() plt.savefig(***)

牛云企业官网小程序,外卖cps权益变现,uniCloud云开发无需购买服务器和域名,助力每一位创业者。

技术优势 基于 uniapp uniCloud 研发&#xff0c;无需购买服务器和域名&#xff0c;uniCloud 是 DCloud 联合阿里云、腾讯云 serverless 构建。从此不用关心服务器运维、弹性扩容、大并发承载、防DDoS攻击等&#xff0c;轻松应对高并发应用&#xff0c; 上图 小程序页面 体…

C++测试

开始对C嘎嘎下手&#xff01; 1.有关char数组 定义长度为5&#xff0c;但是实际长度是定义长度减1 突然就想到计网安全中的栈溢出问题了&#xff0c;C语言是不检查你是否越界的&#xff0c;如果通过让实参溢出覆盖掉原程序的返回地址&#xff0c;通过精心控制是可以让计算机执…

Linux系统之安装showdoc文档工具

Linux系统之部署showdoc文档工具 一、showdoc介绍1.1 showdoc简介1.2 showdoc功能 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查本地yum仓库状态 四、安装httpd服务4.1 安装httpd4.2 启动httpd服务…

chatgpt赋能python:Python新手常见的报错提示及解决方法

Python新手常见的报错提示及解决方法 Python是一种非常流行的编程语言。对于新手来说&#xff0c;Python在学习过程中可能会遇到许多报错提示&#xff0c;这些提示可能会让人感到很困惑。本文将介绍Python新手常见的报错提示&#xff0c;并提供解决方法。 IndentationError: …

【如何独自开发一个应用或网站?成本预算是多少?】

下面是一个基本的步骤和估算成本的方法&#xff1a; 需求分析和规划&#xff1a;确定您的产品功能和目标受众&#xff0c;制定详细的需求和功能列表。 设计阶段&#xff1a;根据需求&#xff0c;设计用户界面、数据库结构和系统架构。 开发阶段&#xff1a;编写代码&#xff…

Triton教程---模型设置

Triton教程—模型设置 这是您第一次编写配置文件吗&#xff1f; 查看本指南或本示例&#xff01; Triton系列教程: 快速开始利用Triton部署你自己的模型Triton架构模型仓库存储代理模型设置优化动态批处理 文章目录 Triton教程---模型设置最小模型配置名称、平台和后端模型…