public
T borrowObject(
long
borrowMaxWaitMillis) throws Exception {
assertOpen();
//是否在获取对象的时候检查对象,开启的话则检查【主要是检查过期】
AbandonedConfig ac =
this
.abandonedConfig;
if
(ac !=
null
&& ac.getRemoveAbandonedOnBorrow() &&
(getNumIdle() < 2) &&
(getNumActive() > getMaxTotal() - 3) ) {
removeAbandoned(ac);
}
PooledObject<T> p =
null
;
// Get local copy of current config so it is consistent for entire
// method execution
//当池耗尽的时候是否block,如果block的话则会idleObjects.pollFirst(borrowMaxWaitMillis,TimeUnit.MILLISECONDS);否则直接throw new NoSuchElementException("Pool exhausted");
boolean blockWhenExhausted = getBlockWhenExhausted();
boolean create;
long
waitTime = 0;
while
(p ==
null
) {
create =
false
;
if
(blockWhenExhausted) {
p = idleObjects.pollFirst();
if
(p ==
null
) {
create =
true
;
p = create();
}
if
(p ==
null
) {
if
(borrowMaxWaitMillis < 0) {
p = idleObjects.takeFirst();
}
else
{
waitTime = System.currentTimeMillis();
p = idleObjects.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 = idleObjects.pollFirst();
if
(p ==
null
) {
create =
true
;
p = create();
}
if
(p ==
null
) {
throw
new
NoSuchElementException(
"Pool exhausted"
);
}
if
(!p.allocate()) {
p =
null
;
}
}
if
(p !=
null
) {
try
{
//激活对象
factory.activateObject(p);
}
catch
(Exception e) {
try
{
destroy(p);
}
catch
(Exception e1) {
// Ignore - activation failure is more important
}
p =
null
;
if
(create) {
NoSuchElementException nsee =
new
NoSuchElementException(
"Unable to activate object"
);
nsee.initCause(e);
throw
nsee;
}
}
//如果获取对象是检查则validateObject
if
(p !=
null
&& getTestOnBorrow()) {
boolean validate =
false
;
Throwable validationThrowable =
null
;
try
{
validate = factory.validateObject(p);
}
catch
(Throwable t) {
PoolUtils.checkRethrow(t);
validationThrowable = t;
}
//检查不通过则destroy
if
(!validate) {
try
{
destroy(p);
destroyedByBorrowValidationCount.incrementAndGet();
}
catch
(Exception e) {
// Ignore - validation failure is more important
}
p =
null
;
if
(create) {
NoSuchElementException nsee =
new
NoSuchElementException(
"Unable to validate object"
);
nsee.initCause(validationThrowable);
throw
nsee;
}
}
}
}
}
updateStatsBorrow(p, waitTime);
return
p.getObject();
}