文章目录
预备流程梳理
新建Jedis—>新建BinaryJedis—>新建Client—>新建Connection—>建立socket(初始化OutputStream和InputStream)
JedisPool:装有多个Jedis实例的池子。
获取Jedis实例
GenericObjectPool.borrowObject(final long borrowMaxWaitMillis)
public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
assertOpen();
final AbandonedConfig ac = this.abandonedConfig;
// 首先移除很久未使用的实例
if (ac != null && ac.getRemoveAbandonedOnBorrow() &&
(getNumIdle() < 2) &&
(getNumActive() > getMaxTotal() - 3) ) {
removeAbandoned(ac);
}
PooledObject<T> p = null;
// 获取 当没有可用的实例时,是否阻塞
final boolean blockWhenExhausted = getBlockWhenExhausted();
boolean create;
final long waitTime = System.currentTimeMillis();
while (p == null) {
create = false;
p = idleObjects.pollFirst();
// 没有可用的实例时,先创建
if (p == null) {
p = create();
if (p != null) {
create = true;
}
}
//创建失败,但允许等待获取可用连接则:
if (blockWhenExhausted) {
if (p == null) {
// 1.一直阻塞至能获取到实例
if (borrowMaxWaitMillis < 0) {
p = idleObjects.takeFirst();
} else {
// 2.等待一段时间获取实例
p = idleObjects.pollFirst(borrowMaxWaitMillis,
TimeUnit.MILLISECONDS);
}
}
if (p == null) {
throw new NoSuchElementException(
"Timeout waiting for idle object");
}
} else {
if (p == null) {
throw new NoSuchElementException("Pool exhausted");
}
}
if (!p.allocate()) {
p = null;
}
// 获取到则激活实例和简单测试实例是否可用
......
}
// 更新状态
updateStatsBorrow(p, System.currentTimeMillis() - waitTime);
return p.getObject();
}
创建实例
GenericObjectPool.create() :其中 createCount记录已经创建的数量,makeObjectCountLock表示正在创建的数量
private PooledObject<T> create() throws Exception {
int localMaxTotal = getMaxTotal();
// 设置最大数量
if (localMaxTotal < 0) {
localMaxTotal = Integer.MAX_VALUE;
}
// true:创建一个实例并返回该实例
// false: 返回null
// null: 继续循环
Boolean create = null;
while (create == null) {
synchronized (makeObjectCountLock) {
final long newCreateCount = createCount.incrementAndGet();
if (newCreateCount > localMaxTotal) {
// 已经达到容量,不必再继续创建新的实例,把 上面createCount.incrementAndGet() 减回来
createCount.decrementAndGet();
if (makeObjectCount == 0) {
// 没有正在创建的实例,说明已经达到最大容量,直接返回false
create = Boolean.FALSE;
} else {
// 有正在创建的实例,等待一段时间获取实例
makeObjectCountLock.wait();
}
} else {
// 还没到最大容量,直接创建实例
makeObjectCount++;
create = Boolean.TRUE;
}
}
}
if (!create.booleanValue()) {
return null;
}
final PooledObject<T> p;
try {
p = factory.makeObject();
} catch (final Exception e) {
createCount.decrementAndGet();
throw e;
} finally {
synchronized (makeObjectCountLock) {
// 创建完makeObjectCount要减回去,且唤醒之前wait的
makeObjectCount--;
makeObjectCountLock.notifyAll();
}
}
final AbandonedConfig ac = this.abandonedConfig;
if (ac != null && ac.getLogAbandoned()) {
p.setLogAbandoned(true);
// TODO: in 3.0, this can use the method defined on PooledObject
if (p instanceof DefaultPooledObject<?>) {
((DefaultPooledObject<T>) p).setRequireFullStackTrace(ac.getRequireFullStackTrace());
}
}
// 正真创建完一个实例,则createdCount递增
createdCount.incrementAndGet();
allObjects.put(new IdentityWrapper<>(p.getObject()), p);
return p;
}
归还Jedis实例
public void close() {
if (dataSource != null) {
Pool<Jedis> pool = this.dataSource;
this.dataSource = null;
// 该连接是否被破坏
if (client.isBroken()) {
// 销毁实例,创建新实例
pool.returnBrokenResource(this);
} else {
// 直接返回
pool.returnResource(this);
}
} else {
// 关闭client
super.close();
}
}