常量池
在Java程序中,有很多的东西是永恒的,不会在运行过程中变化。比如一个类的名字,一个类字段的名字/所属类型,一个类方法的名字/返回类型/参数名与所属类型,一个常量,还有在程序中出现的大量的字面值。
而这些在JVM解释执行程序的时候是非常重要的。编译器将源程序编译成class文件后,会用一部分字节分类存储这些代码。而这些字节我们就称为常量池。JVM加载class后,在方法区中为它们开辟了空间,于是便成为一个“池”。
如以下存放在常量池中的有:ClassTest
、String
、itemS
、我们
、int
、iteml
、100
、setItemS
、para
public class ClassTest {
private String itemS ="我们 ";
private final int itemI =100 ;
public void setItemS (String para ){...}
}
正如上面所示,一个程序中有很多永恒的类似上面列出的代码部分。每一个都是常量池中的一个常量表(常量项)。而这些常量表之间又有不同,class文件共有11种常量表,如下所示:
java的八大包装器类型的6种都有常量池,分为是Integer
,Boolean
,Charactor
,Short
,Long
,Byte
。
而其中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™ 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();
线程池
四种线程池类型:
- CachedThreadPool-----------<SynchronousQueue>
- 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
- FixedThreadPool-----------<LinkedBlockingQueue>
- 创建一个定长线程池,可控制线程最大并发数,超出的线程会在你队列中等待,线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
- ScheduledThreadPool-----------<DelayedWorkQueue>
- 创建一个定长的线程池,支持定时即周期性任务执行。
- SingleThreadPool-----------<LinkedBlockingQueue>
- 创建一个单线程化的线程池,它只会用唯一 的工作线程来执行任务,保证所有任务按照指定顺序(FIFO)执行,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
使用:
- 创建一个单线程化的线程池,它只会用唯一 的工作线程来执行任务,保证所有任务按照指定顺序(FIFO)执行,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
ExecutorService cachedPool = Executors.newCachedThreadPool();
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
ExecutorService scheduledPool = Executors.newScheduledThreadPool(5);
ExecutorService singlePool = Executors.newSingleThreadExecutor();
连接池
为了应对,从发起到建立连接这样的过程频繁发生,而这样的过程却是短暂的。也就有了连接池,甚至资源池,对象池的概念。把已经建立的连接用集合保存起来,这就是连接池的根本。