package com.xinyartech.mymvpdemo.okhttp.myOkhttp.pool;
import android.util.Log;
import java.util.Deque;
import java.util.Iterator;
import java.util.concurrent.*;
/**
* <pre>
* author : QB
* time : 2019/8/27
* version : v1.0.0
* desc : 连接池
* </pre>
*/
public class ConnectionPool {
/**
* 最大的等待时间,超过这个时间直接回收
*/
private long keepLive;
/**
* 队列,存放连接池对象
*/
private Deque<ConnectionHttp> queueList = new LinkedBlockingDeque<>();
/**
* 判断回收线程是否启动
*/
private boolean isRunning = false;
/**
* 闲置时间
*/
private long idleTime;
public ConnectionPool() {
this(1, TimeUnit.SECONDS);
}
public ConnectionPool(long minute, TimeUnit timeUnit) {
keepLive = timeUnit.toMillis(minute);
}
/**
* 回收线程,将超时的连接对象回收掉
*/
Runnable clearRunnable = new Runnable() {
@Override
public void run() {
while (true) {
long waitTime = clean(System.currentTimeMillis());
if (waitTime > 0) {
//加锁,防止多次等待
synchronized (ConnectionPool.this) {
try {
ConnectionPool.this.wait(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
//说明队列中没有等待了
System.out.println("没有连接对像>>>>");
return;
}
}
}
};
/**
* 开始清除
*/
private long clean(long currentTime) {
Iterator<ConnectionHttp> iterator = queueList.iterator();
//下一次执行runnable循环的等待时间
long waitTime = -1;
System.out.println("开始清理连接对像>>>>");
synchronized (this) {
while (iterator.hasNext()) {
ConnectionHttp next = iterator.next();
idleTime = currentTime - next.getLastTime();
//空闲时间大于最大允许的闲置时间,移除
if (idleTime > keepLive) {
//移除连接对象
queueList.remove(next);
//关闭对象的socket连接
next.closeSocket();
System.out.println("清理连接对像>>>>");
}
//找到闲置时间最长的那个连接对象
if (waitTime < idleTime) {
waitTime = idleTime;
}
}
//计算清理线程需要等待的时间
if (waitTime > 0) {
return keepLive - waitTime;
}
}
return waitTime;
}
/**
* 创建缓存队列
*/
private ExecutorService executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);//设置成守护线程,生命周期跟随程序
return thread;
}
});
/**
* 添加连接池对象
* 这里开始启动线程
*/
public synchronized void addConnection(ConnectionHttp connectionHttp) {
if (!isRunning) {
isRunning = true;
executorService.execute(clearRunnable);
}
queueList.add(connectionHttp);
System.out.println("队列长度》》》 "+queueList.size());
}
/**
* 拿到连接池对象
*/
public ConnectionHttp take(String host, int port) {
Iterator<ConnectionHttp> iterator = queueList.iterator();
while (iterator.hasNext()) {
ConnectionHttp httpConnection = iterator.next();
if (httpConnection.isConnect(host, port)) {
// 移除
iterator.remove();
// 代表我们找到了 可以复用的
return httpConnection;
}
}
return null;
}
}