JDK源码分析

java之常量池、线程池、连接池

2018-09-14  本文已影响90人  Sophie12138

常量池

在Java程序中,有很多的东西是永恒的,不会在运行过程中变化。比如一个类的名字,一个类字段的名字/所属类型,一个类方法的名字/返回类型/参数名与所属类型,一个常量,还有在程序中出现的大量的字面值。

而这些在JVM解释执行程序的时候是非常重要的。编译器将源程序编译成class文件后,会用一部分字节分类存储这些代码。而这些字节我们就称为常量池。JVM加载class后,在方法区中为它们开辟了空间,于是便成为一个“池”。

如以下存放在常量池中的有:ClassTestStringitemS我们intiteml100setItemSpara

public class ClassTest {
    private String itemS ="我们 ";
    private final int itemI =100 ;
    public void setItemS (String para ){...}
}

正如上面所示,一个程序中有很多永恒的类似上面列出的代码部分。每一个都是常量池中的一个常量表(常量项)。而这些常量表之间又有不同,class文件共有11种常量表,如下所示:


捕获.PNG

java的八大包装器类型的6种都有常量池,分为是IntegerBooleanCharactorShortLongByte
而其中Integer默认是-128~127的范围,但是可以通过jvm参数设置最大数值为MAX_VALUE-127-1,而其他的数值类型均为-128~127

Integer常量池设计核心代码如下:

    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) {
                try {
                    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);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

而String隐藏了常量池的具体实现,通过intern对外提供常量池技术。

    /**
     * Returns a canonical representation for the string object.
     * <p>
     * A pool of strings, initially empty, is maintained privately by the
     * class {@code String}.
     * <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this {@code String} object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this {@code String} object is added to the
     * pool and a reference to this {@code String} object is returned.
     * <p>
     * It follows that for any two strings {@code s} and {@code t},
     * {@code s.intern() == t.intern()} is {@code true}
     * if and only if {@code s.equals(t)} is {@code true}.
     * <p>
     * All literal strings and string-valued constant expressions are
     * interned. String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
    public native String intern();

线程池

四种线程池类型:

ExecutorService cachedPool = Executors.newCachedThreadPool();
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
ExecutorService scheduledPool = Executors.newScheduledThreadPool(5);
ExecutorService singlePool = Executors.newSingleThreadExecutor();

连接池

为了应对,从发起到建立连接这样的过程频繁发生,而这样的过程却是短暂的。也就有了连接池,甚至资源池,对象池的概念。把已经建立的连接用集合保存起来,这就是连接池的根本。

又比如连接池,C3P0,DBCP,BoneCP

上一篇下一篇

猜你喜欢

热点阅读