gu.simplemq.pool.BaseMQPool Maven / Gradle / Ivy
package gu.simplemq.pool;
import java.io.Closeable;
import java.net.URI;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.common.base.Preconditions.checkState;
/**
* 支持嵌套调用的消息系统连接对象管理基类
* @author guyadong
*
* @param 资源池管理的对象类型
*/
public abstract class BaseMQPool implements Closeable{
protected volatile boolean closed = false;
/** apply/free 嵌套计数 */
private final ThreadLocal tlsNestCount = new ThreadLocal(){
@Override
protected AtomicInteger initialValue() {
return new AtomicInteger(0);
}
};
/**
* 当前线程下的资源对象
*/
private final ThreadLocal tlsResource = new ThreadLocal();
protected BaseMQPool() {
}
/**
* 从资源池获取一个资源对象
* 对于调用此方法获取的实例,当不再使用时需要调用{@link #release(Object)}释放
* @return 资源对象
*/
public abstract R borrow();
/**
* 将资源对象归还到资源池
* @param r 资源对象
*/
public abstract void release(R r) ;
/**
* 申请当前线程使用的资源对象,不可跨线程使用
* 使用完后调用 {@link #free()}释放对象
* @throws MQPoolException
*/
public final R apply() throws MQPoolException{
R r = tlsResource.get();
if(null == r){
r = borrow();
this.tlsResource.set(r);
}
if(tlsNestCount.get() == null){
tlsNestCount.set(new AtomicInteger(0));
}
tlsNestCount.get().incrementAndGet();
return r;
}
/**
* 释放当前线程使用的资源
* 必须与{@link #apply()}配对使用
*/
public final void free(){
R r = tlsResource.get();
checkState(r != null && tlsNestCount.get() != null, "apply/free mismatch");
if(0 == tlsNestCount.get().decrementAndGet()){
release(r);
tlsResource.remove();
tlsNestCount.remove();
}
}
/**
* @return
*/
public abstract URI getCanonicalURI();
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(getClass().getSimpleName());
builder.append("@");
builder.append(hashCode());
builder.append("[URI=");
builder.append(getCanonicalURI());
builder.append("]");
return builder.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BaseMQPool)) {
return false;
}
@SuppressWarnings("rawtypes")
BaseMQPool other = (BaseMQPool) obj;
return getCanonicalURI().equals(other.getCanonicalURI());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
URI uri = getCanonicalURI();
result = prime * result + ((uri == null) ? 0 : uri.hashCode());
return result;
}
/**
* Has this pool instance been closed.
* @return true
when this pool has been closed.
*/
public boolean isClosed() {
return closed;
}
@SuppressWarnings("serial")
public static class MQPoolException extends RuntimeException{
public MQPoolException(Throwable cause) {
super(cause);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy