zoukankan      html  css  js  c++  java
  • 设计模式课程 设计模式精讲 13-3 享元模式源码解析

    1    享元模式源码解析

    1.1  享元模式源码解析1(jdk中的应用)

    1.2  享元模式源码解析2(tomcat中的应用)

    1    享元模式源码解析
    1.1  享元模式源码解析1(jdk中的应用)

    测试类:

    package com.geely.design.pattern.structural.flyweight;
    
    public class Test2 {
        public static void main(String [] args){
            Integer a = 100;
            Integer b = Integer.valueOf(100);
            System.out.println("a==b"+ (a==b));
    
            Integer c = 1000;
            Integer d = Integer.valueOf(1000);
            System.out.println("c==d"+ (c==d));
        }
    }

    Integer类:

    public final class Integer extends Number implements Comparable<Integer> {
    
     /**
         * Returns an {@code Integer} instance representing the specified
         * {@code int} value.  If a new {@code Integer} instance is not
         * required, this method should generally be used in preference to
         * the constructor {@link #Integer(int)}, as this method is likely
         * to yield significantly better space and time performance by
         * caching frequently requested values.
         *
         * This method will always cache values in the range -128 to 127,
         * inclusive, and may cache other values outside of this range.
         * 如果传入的数值在缓存的-127和128之间,那么都会在cache中,否则的话,会new出新的对象,这也是为什么100==100为true,1000==1000为false
         *  test中a,b,c,d都执行了该方法,一共执行了4次   。
    *
    @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } /** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the -XX:AutoBoxCacheMax=<size> option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} } }

    打印日志:

    "C:Program FilesJavajdk1.7.0_79injava.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63738,suspend=y,server=n -javaagent:C:UsersweijingliAppDataLocalTempcapture1jarsdebugger-agent.jar=file:/C:/Users/weijingli/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.7.0_79jrelibcharsets.jar;C:Program FilesJavajdk1.7.0_79jrelibdeploy.jar;C:Program FilesJavajdk1.7.0_79jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.7.0_79jrelibextdnsns.jar;C:Program FilesJavajdk1.7.0_79jrelibextjaccess.jar;C:Program FilesJavajdk1.7.0_79jrelibextlocaledata.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunec.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunmscapi.jar;C:Program FilesJavajdk1.7.0_79jrelibextzipfs.jar;C:Program FilesJavajdk1.7.0_79jrelibjavaws.jar;C:Program FilesJavajdk1.7.0_79jrelibjce.jar;C:Program FilesJavajdk1.7.0_79jrelibjfr.jar;C:Program FilesJavajdk1.7.0_79jrelibjfxrt.jar;C:Program FilesJavajdk1.7.0_79jrelibjsse.jar;C:Program FilesJavajdk1.7.0_79jrelibmanagement-agent.jar;C:Program FilesJavajdk1.7.0_79jrelibplugin.jar;C:Program FilesJavajdk1.7.0_79jrelib
    esources.jar;C:Program FilesJavajdk1.7.0_79jrelib
    t.jar;F:xiangmu3XinIdeadesign_pattern	argetclasses;F:xiangmu3XinFuQiangmavencode
    epoorgapache	omcat	omcat-servlet-api7.0.64	omcat-servlet-api-7.0.64.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworksessionspring-session-core2.1.7.RELEASEspring-session-core-2.1.7.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-webmvc4.0.3.RELEASEspring-webmvc-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-beans4.0.3.RELEASEspring-beans-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-context4.0.3.RELEASEspring-context-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-aop4.0.3.RELEASEspring-aop-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoaopallianceaopalliance1.0aopalliance-1.0.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-core4.0.3.RELEASEspring-core-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-expression4.0.3.RELEASEspring-expression-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-web4.0.3.RELEASEspring-web-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-oxm4.0.3.RELEASEspring-oxm-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-jdbc4.0.3.RELEASEspring-jdbc-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-tx4.0.3.RELEASEspring-tx-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgspringframeworkspring-test4.0.3.RELEASEspring-test-4.0.3.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorgaspectjaspectjweaver1.7.3aspectjweaver-1.7.3.jar;F:xiangmu3XinFuQiangmavencode
    epoorgmybatismybatis-spring1.3.0mybatis-spring-1.3.0.jar;F:xiangmu3XinFuQiangmavencode
    epoorgmybatismybatis3.4.1mybatis-3.4.1.jar;F:xiangmu3XinFuQiangmavencode
    epoorgaspectjaspectjrt1.6.11aspectjrt-1.6.11.jar;F:xiangmu3XinFuQiangmavencode
    epoorgcodehausjacksonjackson-mapper-asl1.9.12jackson-mapper-asl-1.9.12.jar;F:xiangmu3XinFuQiangmavencode
    epoorgcodehausjacksonjackson-core-asl1.9.12jackson-core-asl-1.9.12.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-dbcpcommons-dbcp1.4commons-dbcp-1.4.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-poolcommons-pool1.5.4commons-pool-1.5.4.jar;F:xiangmu3XinFuQiangmavencode
    epochqoslogbacklogback-classic1.1.2logback-classic-1.1.2.jar;F:xiangmu3XinFuQiangmavencode
    epoorgslf4jslf4j-api1.7.6slf4j-api-1.7.6.jar;F:xiangmu3XinFuQiangmavencode
    epochqoslogbacklogback-core1.1.2logback-core-1.1.2.jar;F:xiangmu3XinFuQiangmavencode
    epomysqlmysql-connector-java5.1.6mysql-connector-java-5.1.6.jar;F:xiangmu3XinFuQiangmavencode
    epocomgoogleguavaguava20.0guava-20.0.jar;F:xiangmu3XinFuQiangmavencode
    epoorgapachecommonscommons-lang33.5commons-lang3-3.5.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-collectionscommons-collections3.2.1commons-collections-3.2.1.jar;F:xiangmu3XinFuQiangmavencode
    epojunitjunit4.12junit-4.12.jar;F:xiangmu3XinFuQiangmavencode
    epojoda-timejoda-time2.3joda-time-2.3.jar;F:xiangmu3XinFuQiangmavencode
    epoorghashidshashids1.0.1hashids-1.0.1.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-netcommons-net3.1commons-net-3.1.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-fileuploadcommons-fileupload1.2.2commons-fileupload-1.2.2.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-iocommons-io2.0.1commons-io-2.0.1.jar;F:xiangmu3XinFuQiangmavencode
    epocomgithubpagehelperpagehelper4.1.0pagehelper-4.1.0.jar;F:xiangmu3XinFuQiangmavencode
    epocomgithubmiemiedevmybatis-paginator1.2.17mybatis-paginator-1.2.17.jar;F:xiangmu3XinFuQiangmavencode
    epocomgithubjsqlparserjsqlparser.9.4jsqlparser-0.9.4.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-codeccommons-codec1.10commons-codec-1.10.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-configurationcommons-configuration1.10commons-configuration-1.10.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-langcommons-lang2.6commons-lang-2.6.jar;F:xiangmu3XinFuQiangmavencode
    epocommons-loggingcommons-logging1.1.1commons-logging-1.1.1.jar;F:xiangmu3XinFuQiangmavencode
    epocomgooglezxingcore2.1core-2.1.jar;F:xiangmu3XinFuQiangmavencode
    epocomgooglecodegsongson2.3.1gson-2.3.1.jar;F:xiangmu3XinFuQiangmavencode
    epoorghamcresthamcrest-core1.3hamcrest-core-1.3.jar;F:xiangmu3XinFuQiangmavencode
    epo
    edisclientsjedis2.6.0jedis-2.6.0.jar;F:xiangmu3XinFuQiangmavencode
    epoorgapachecommonscommons-pool22.0commons-pool2-2.0.jar;F:xiangmu3XinFuQiangmavencode
    epoorgprojectlomboklombok1.16.18lombok-1.16.18.jar;F:xiangmu3XinFuQiangmavencode
    epoorg
    edisson
    edisson2.9.0
    edisson-2.9.0.jar;F:xiangmu3XinFuQiangmavencode
    epoio
    etty
    etty-common4.1.8.Final
    etty-common-4.1.8.Final.jar;F:xiangmu3XinFuQiangmavencode
    epoio
    etty
    etty-codec4.1.8.Final
    etty-codec-4.1.8.Final.jar;F:xiangmu3XinFuQiangmavencode
    epoio
    etty
    etty-buffer4.1.8.Final
    etty-buffer-4.1.8.Final.jar;F:xiangmu3XinFuQiangmavencode
    epoio
    etty
    etty-transport4.1.8.Final
    etty-transport-4.1.8.Final.jar;F:xiangmu3XinFuQiangmavencode
    epoio
    etty
    etty-resolver4.1.8.Final
    etty-resolver-4.1.8.Final.jar;F:xiangmu3XinFuQiangmavencode
    epoio
    etty
    etty-handler4.1.8.Final
    etty-handler-4.1.8.Final.jar;F:xiangmu3XinFuQiangmavencode
    epojavaxcachecache-api1.0.0cache-api-1.0.0.jar;F:xiangmu3XinFuQiangmavencode
    epoioprojectreactor
    eactor-stream2.0.8.RELEASE
    eactor-stream-2.0.8.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoioprojectreactor
    eactor-core2.0.8.RELEASE
    eactor-core-2.0.8.RELEASE.jar;F:xiangmu3XinFuQiangmavencode
    epoorg
    eactivestreams
    eactive-streams1.0.0
    eactive-streams-1.0.0.jar;F:xiangmu3XinFuQiangmavencode
    epocomfasterxmljacksondataformatjackson-dataformat-yaml2.6.7jackson-dataformat-yaml-2.6.7.jar;F:xiangmu3XinFuQiangmavencode
    epoorgyamlsnakeyaml1.15snakeyaml-1.15.jar;F:xiangmu3XinFuQiangmavencode
    epocomfasterxmljacksoncorejackson-core2.6.7jackson-core-2.6.7.jar;F:xiangmu3XinFuQiangmavencode
    epocomfasterxmljacksoncorejackson-databind2.6.7jackson-databind-2.6.7.jar;F:xiangmu3XinFuQiangmavencode
    epocomfasterxmljacksondataformatjackson-dataformat-avro2.9.0jackson-dataformat-avro-2.9.0.jar;F:xiangmu3XinFuQiangmavencode
    epocomfasterxmljacksoncorejackson-annotations2.9.0jackson-annotations-2.9.0.jar;F:xiangmu3XinFuQiangmavencode
    epoorgapacheavroavro1.8.1avro-1.8.1.jar;F:xiangmu3XinFuQiangmavencode
    epocom	houghtworksparanamerparanamer2.7paranamer-2.7.jar;F:xiangmu3XinFuQiangmavencode
    epoorgxerialsnappysnappy-java1.1.1.3snappy-java-1.1.1.3.jar;F:xiangmu3XinFuQiangmavencode
    epoorgapachecommonscommons-compress1.8.1commons-compress-1.8.1.jar;F:xiangmu3XinFuQiangmavencode
    epoorg	ukaanixz1.5xz-1.5.jar;F:xiangmu3XinFuQiangmavencode
    epocomsunfacesjsf-api1.2jsf-api-1.2.jar;D:javadevolopKitideaanZhIntelliJ IDEA Community Edition 2018.1.4libidea_rt.jar" com.geely.design.pattern.structural.flyweight.Test2
    Connected to the target VM, address: '127.0.0.1:63738', transport: 'socket'
    a==btrue
    c==dfalse
    Disconnected from the target VM, address: '127.0.0.1:63738', transport: 'socket'
    
    Process finished with exit code 0
    1.2  享元模式源码解析2(tomcat中的应用)

    父类(GenericObjectPoolConfig):添加了一些默认的配置

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.apache.commons.pool2.impl;
    
    public class GenericObjectPoolConfig extends BaseObjectPoolConfig {
        public static final int DEFAULT_MAX_TOTAL = 8;
        public static final int DEFAULT_MAX_IDLE = 8;
        public static final int DEFAULT_MIN_IDLE = 0;
        private int maxTotal = 8;
        private int maxIdle = 8;
        private int minIdle = 0;
    
        public GenericObjectPoolConfig() {
        }
    
        public int getMaxTotal() {
            return this.maxTotal;
        }
    
        public void setMaxTotal(int maxTotal) {
            this.maxTotal = maxTotal;
        }
    
        public int getMaxIdle() {
            return this.maxIdle;
        }
    
        public void setMaxIdle(int maxIdle) {
            this.maxIdle = maxIdle;
        }
    
        public int getMinIdle() {
            return this.minIdle;
        }
    
        public void setMinIdle(int minIdle) {
            this.minIdle = minIdle;
        }
    
        public GenericObjectPoolConfig clone() {
            try {
                return (GenericObjectPoolConfig)super.clone();
            } catch (CloneNotSupportedException var2) {
                throw new AssertionError();
            }
        }
    }

    子类(GenericKeyedObjectPoolConfig)(选2版本):

    通过object的双端队列来保存对象池的对象,重点看p是怎么给值的。

    /**
       *     借
       */
     public T borrowObject(K key, long borrowMaxWaitMillis) throws Exception {
            this.assertOpen();
            PooledObject<T> p = null;
            boolean blockWhenExhausted = this.getBlockWhenExhausted();
            long waitTime = 0L;
            GenericKeyedObjectPool.ObjectDeque objectDeque = this.register(key);
    
            try {
                while(p == null) {
                    boolean create = false;
                    if (blockWhenExhausted) {
                        p = (PooledObject)objectDeque.getIdleObjects().pollFirst();
                        if (p == null) {
                            create = true;
                            p = this.create(key);
                        }
    
                        if (p == null) {
                            if (borrowMaxWaitMillis < 0L) {
                                p = (PooledObject)objectDeque.getIdleObjects().takeFirst();
                            } else {
                                waitTime = System.currentTimeMillis();
                                p = (PooledObject)objectDeque.getIdleObjects().pollFirst(borrowMaxWaitMillis, TimeUnit.MILLISECONDS);
                                waitTime = System.currentTimeMillis() - waitTime;
                            }
                        }
    
                        if (p == null) {
                            throw new NoSuchElementException("Timeout waiting for idle object");
                        }
    
                        if (!p.allocate()) {
                            p = null;
                        }
                    } else {
                        p = (PooledObject)objectDeque.getIdleObjects().pollFirst();
                        if (p == null) {
                            create = true;
                            p = this.create(key);
                        }
    
                        if (p == null) {
                            throw new NoSuchElementException("Pool exhausted");
                        }
    
                        if (!p.allocate()) {
                            p = null;
                        }
                    }
    
                    if (p != null) {
                        try {
                            this.factory.activateObject(key, p);
                        } catch (Exception var22) {
                            try {
                                this.destroy(key, p, true);
                            } catch (Exception var21) {
                                ;
                            }
    
                            p = null;
                            if (create) {
                                NoSuchElementException nsee = new NoSuchElementException("Unable to activate object");
                                nsee.initCause(var22);
                                throw nsee;
                            }
                        }
    
                        if (p != null && this.getTestOnBorrow()) {
                            boolean validate = false;
                            Throwable validationThrowable = null;
    
                            try {
                                validate = this.factory.validateObject(key, p);
                            } catch (Throwable var20) {
                                PoolUtils.checkRethrow(var20);
                                validationThrowable = var20;
                            }
    
                            if (!validate) {
                                try {
                                    this.destroy(key, p, true);
                                    this.destroyedByBorrowValidationCount.incrementAndGet();
                                } catch (Exception var19) {
                                    ;
                                }
    
                                p = null;
                                if (create) {
                                    NoSuchElementException nsee = new NoSuchElementException("Unable to validate object");
                                    nsee.initCause(validationThrowable);
                                    throw nsee;
                                }
                            }
                        }
                    }
                }
            } finally {
                this.deregister(key);
            }
    
            this.updateStatsBorrow(p, waitTime);
            return p.getObject();
        }
    
    
    /**
       *     还
       */
      public void returnObject(K key, T obj) {
            GenericKeyedObjectPool<K, T>.ObjectDeque<T> objectDeque = (GenericKeyedObjectPool.ObjectDeque)this.poolMap.get(key);
            PooledObject<T> p = (PooledObject)objectDeque.getAllObjects().get(obj);
            if (p == null) {
                throw new IllegalStateException("Returned object not currently part of this pool");
            } else {
                long activeTime = p.getActiveTimeMillis();
                if (this.getTestOnReturn() && !this.factory.validateObject(key, p)) {
                    try {
                        this.destroy(key, p, true);
                    } catch (Exception var11) {
                        this.swallowException(var11);
                    }
    
                    this.updateStatsReturn(activeTime);
                } else {
                    try {
                        this.factory.passivateObject(key, p);
                    } catch (Exception var13) {
                        this.swallowException(var13);
    
                        try {
                            this.destroy(key, p, true);
                        } catch (Exception var10) {
                            this.swallowException(var10);
                        }
    
                        this.updateStatsReturn(activeTime);
                        return;
                    }
    
                    if (!p.deallocate()) {
                        throw new IllegalStateException("Object has already been retured to this pool");
                    } else {
                        int maxIdle = this.getMaxIdlePerKey();
                        LinkedBlockingDeque<PooledObject<T>> idleObjects = objectDeque.getIdleObjects();
                        if (this.isClosed() || maxIdle > -1 && maxIdle <= idleObjects.size()) {
                            try {
                                this.destroy(key, p, true);
                            } catch (Exception var12) {
                                this.swallowException(var12);
                            }
                        } else if (this.getLifo()) {
                            idleObjects.addFirst(p);
                        } else {
                            idleObjects.addLast(p);
                        }
    
                        if (this.hasBorrowWaiters()) {
                            this.reuseCapacity();
                        }
    
                        this.updateStatsReturn(activeTime);
                    }
                }
            }
        }

    工厂类:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.apache.commons.pool2;
    
    public interface KeyedPooledObjectFactory<K, V> {
       //创建对象方法
        PooledObject<V> makeObject(K var1) throws Exception;
    
      //销毁对象方法
        void destroyObject(K var1, PooledObject<V> var2) throws Exception;
    
      //验证对象方法
        boolean validateObject(K var1, PooledObject<V> var2);
      //激活对象方法,用的时候激活
        void activateObject(K var1, PooledObject<V> var2) throws Exception;
      //钝化对象方法,不用的钝化
        void passivateObject(K var1, PooledObject<V> var2) throws Exception;
    }
  • 相关阅读:
    React初识整理(二)--生命周期的方法
    React初识整理(一)
    前后端分离浅析
    url地址数据参数转化JSON对象(js三种方法实现)
    js和JQuery中的获取宽、高、位置等方法整理
    游民轮播图效果实现
    焦点轮播图效果实现
    iOS开发debug集锦
    实现一个 RESTful API 服务器
    从iOS的图片圆角想到渲染
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/11519272.html
Copyright © 2011-2022 走看看