public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
注意:
Byte, Short, Long 緩存的範圍都是 -128~127
Character 緩存的範圍是 0~127
Integer的預設範圍是 -128~127
最小值不能變
但最大值可以通過調整虛拟機參數 `
-Djava.lang.Integer.IntegerCache.high` 來改變
Boolean 緩存了 TRUE 和 FALS
2.2 String 串池
享元模式、不可變類。(詳情見jvm第一天,記憶體結構文章對串池的記錄)
2.3 BigDecimal BigInteger
享元模式、不可變類。(用AtomicReference<BigDecimal> ,保護BigDecimal ,是因為雖然BigDecimal 是線程安全的,單個方法是原子的,線程安全的,但是并不能保證多個方法的組合是線程安全的。其他不可變類也一樣。)
3. DIY,自定義連接配接池
例如:一個線上商城應用,QPS 達到數千,如果每次都重新建立和關閉資料庫連接配接,性能會受到極大影響。 這時預先建立好一批連接配接,放入連接配接池。一次請求到達後,從連接配接池擷取連接配接,使用完畢後再還回連接配接池,這樣既節約了連接配接的建立和關閉時間,也實作了連接配接的重用,不至于讓龐大的連接配接數壓垮資料庫。
class Pool {
// 1. 連接配接池大小
private final int poolSize;
// 2. 連接配接對象數組
private Connection[] connections;
// 3. 連接配接狀态數組 0 表示空閑, 1 表示繁忙
private AtomicIntegerArray states;
// 4. 構造方法初始化
public Pool(int poolSize) {
this.poolSize = poolSize;
this.connections = new Connection[poolSize];
this.states = new AtomicIntegerArray(new int[poolSize]);
for (int i = 0; i < poolSize; i++) {
connections[i] = new MockConnection("連接配接" + (i+1));
}
}
// 5. 借連接配接
public Connection borrow() {
while(true) {
for (int i = 0; i < poolSize; i++) {
// 擷取空閑連接配接
if(states.get(i) == 0) {
if (states.compareAndSet(i, 0, 1)) {
log.debug("borrow {}", connections[i]);
return connections[i];
}
}
}
// 如果沒有空閑連接配接,目前線程進入等待
synchronized (this) {
try {
log.debug("wait...");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 6. 歸還連接配接
public void free(Connection conn) {
for (int i = 0; i < poolSize; i++) {
if (connections[i] == conn) {
states.set(i, 0);
synchronized (this) {
log.debug("free {}", conn);
this.notifyAll();
}
break;
}
}
}
}
class MockConnection implements Connection {
// 實作略
}