• 【面试:并发篇35:多线程:设计模式】享元模式


    【面试:并发篇35:多线程:设计模式】享元模式

    00.前言

    如果有任何问题请指出,感谢。

    01.介绍

    保护性拷贝介绍

    我之前的一篇文章浅显的模拟过String类 当时是为了探究为什么String类是不可变类型 文章地址在
    https://blog.csdn.net/m0_71229547/article/details/125757561?spm=1001.2014.3001.5502
    里面重要的结论就是 因为value数组是final修饰的 导致地址引用不可改变 所以Sting类的赋值 或者 获取子类的这种方法 其实都是再新new一个对象 然后返回,所以String类每次操作后返回的对象都是新的对象所以不可变,大家也可以看一下String类的substring方法

    可以看出substring方法也是返回一个新的对象,这种通过创建副本对象来避免共享的手段称之为 保护性拷贝

    享元模式介绍

    保护性拷贝会出现说明问题就是如果对String类操作过多 势必会创建出非常多的对象 很显然是不合适的,所以出现了享元模式 它的使用场景是 当需要重用的数量有限的同一类对象时,例如我们的字符串 假如某个字符串已经有了 我们可以直接用这个字符串对象 而不用再重写创建一个

    02.享元模式在常见类中的体现

    包装类

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

    注意

    1.Byte Short Long缓存的范围都是-128-127
    2.Character缓存的范围是0-127
    3.Integer的默认范围是-128-127
    最小值不能变
    但是最大值可以通过调整虚拟机参数 -Djava.lang.Integer.IntergerCache.high来改变
    4.Boolean缓存了TRUE和FALSE

    String类

    String类是我们日常使用中最常用的类 所以它的优化很重要,在JVM中有一个字符串常量池,具体场景是这样

    	String a = "ss"; // 如果"ss"还没有创建 就创建 并且缓存到字符串常量池
    	String b = "ss"; // 如果创建过了 就从字符串常量池中获取"ss"的地址 并赋值给b
    
    • 1
    • 2

    验证1

    	public class TestXYMS {  
    	    public static void main(String[] args) {  
    	        String a = new String("ss");  
    	        String b = new String("ss");  
    	        System.out.println(a == b);  
    	    }  
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果

    false

    解释
    此时我们都是通过new来创建 并没有从字符串常量池中获取 所以为false

    验证2

    	public class TestXYMS {  
    	    public static void main(String[] args) {  
    	        String a = "ss";  
    	        String b = "ss";  
    	        System.out.println(a == b);  
    	    }  
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果

    true

    解释
    a = “ss” 创建了"ss"对象 并缓存到了常量池,b = “ss” 从常量池中获取

    验证3

    public class TestXYMS {  
        public static void main(String[] args) {  
            String t = new String("ss");  
            String a = t.intern(); // 从常量池中获取t的值
            String b = "ss";  
            System.out.println(a == b);  
        }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果

    true

    解释
    new String(“ss”)后 "ss"缓存到字符串常量池 然后通过t.intern()可以从常量池获取到,通过b = "ss"也可以获取

  • 相关阅读:
    “px、pt、ppi、dpi、dp、sp”全攻略
    #循循渐进学51单片机#点亮你的LED#not.2
    【附源码】计算机毕业设计java租车信息管理系统设计与实现
    Vue15 计算属性VS监视属性(侦听属性)
    Metabase学习教程:仪表盘-1
    版本控制系统-SVN
    js日期排序
    Java设计模式——代理模式
    最新AI创作系统源码ChatGPT源码+附详细搭建部署教程+AI绘画系统+支持国内AI提问模型
    I/O接口
  • 原文地址:https://blog.csdn.net/m0_71229547/article/details/126080299