• “节省内存、提升性能:享元模式的神奇之处“


    概念

    享元模式的本质是缓存共享对象,降低内存消耗。

    是对象池的的一种实现,一句话用到了缓存了对方和池化技术的地方绝大多是享元模式的体现。

    例如线程池,数据库连接池,字符串常量池

    应用示例

    String中的享元模式

    public class StringTest {
        public static void main(String[] args) {
            String s1 = "hello";
            String s2 = "hello";
            String s3 = "he" + "llo";
            String s4 = "hel" + new String("lo");
            String s5 = new String("hello");
            String s6 = s5.intern();  //将字符串对象添加到字符串常量池中,并返回常量池中的引用
    
            String s7 = "h";
            String s8 = "ello";
            String s9 = s7 + s8;
            System.out.println(s1==s2);//true  JDK 只会在常量池保存一个副本
            System.out.println(s1==s3);//true  JDK的一个优化,在编译阶段优化成“hello"
            System.out.println(s1==s4);//false new创建的对象都是在堆中
            System.out.println(s1==s9);//false JDK不会对变量进行优化
            System.out.println(s4==s5);//false
            System.out.println(s1==s6);//true。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Integer中的享元模式

    public class IntegerTest {
        public static void main(String[] args) {
    
            Integer a = Integer.valueOf(100);
            Integer b = 100;
    
            Integer c = Integer.valueOf(1000);
            Integer d = 1000;
    
            System.out.println("a==b:" + (a==b));
            System.out.println("c==d:" + (c==d));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果:
    在这里插入图片描述

    WHAT FUCK???。

    我们进入源码看下:
    在这里插入图片描述
    从这个图上面我们可以看到valueOf方法是有个取值范围的,在这个取值范围之内的是对我们进行了自动拆箱装箱的优化,但是超过了范围就会给我们新建一个对象

    我们看看具体的取值范围
    在这里插入图片描述
    从IntegerCache中我们可以看到取值范围为-128-127,1000超过了范围所以会new 一个新的对象。

    手写简易连接池

    public class ConnectionPool {
        private Vector<Connection> pool;
    
    
        private String url="jdbc:mysql://localhost:3306/test";
        private String username="root";
        private String password="root";
        private String driverClassName="com.mysql.jdbc.Driver";
        private int poolSize=100;
    
        public ConnectionPool(){
            pool=new Vector<Connection>(poolSize);
    
    
                try {
                    Class.forName(driverClassName);
                    for (int i = 0; i < poolSize; i++) {
                        Connection connection = DriverManager.getConnection(url);
                        pool.add(connection);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
    
        }
    
        public synchronized Connection getConnection() {
            if(pool.size() >0){
                Connection connection = pool.get(0);
                pool.remove(connection);
                return connection;
            }
            return null;
        }
    
        public synchronized void relase(Connection connection){
            pool.add(connection);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    享元模式的内部状态和外部状态

    内部状态

    存储在享元对象内部且不会随环境的改变而改变,数据库连接池中的连接配置信息就是不变的。

    外部状态

    外部状态指对象得以依赖的一个标记,是随环境的改变而改变的,简单来说就是连接对象有一个状态判断是否可用。

    MySQL连接池升级版

    https://blog.51cto.com/doujh/1937231

  • 相关阅读:
    Serializable自定义序列化测试
    C语言学习笔记(十八)
    .NET ADO.NET和数据库的连接、 数据库连接池
    linux环境下的MySQL UDF提权
    【linux】初识进程
    这代码运行超时,怎么优化
    Webpack 5 集成 ESLint 的方法
    【Android】在使用约束布局(ConstraintLayout)中,当某个子View发生隐藏后,某个View无法正确显示了
    客户端日志打印规范
    cmake(1)
  • 原文地址:https://blog.csdn.net/Hi_alan/article/details/134097459