Created
June 6, 2018 10:47
-
-
Save Coneboy-k/4c0cc857425e32f80a8a0bf1739d28be to your computer and use it in GitHub Desktop.
基于HashedWheelTimer 的对象池
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Slf4j | |
public abstract class AbsTimerItem { | |
private static final long MIN_TIMEOUT_MILLIS = 1L; | |
private HashedWheelTimer timer; | |
private long readerIdleTimeMillis; | |
private long writerIdleTimeMillis; | |
private volatile int state; // 0 - none, 1 - initialized, 2 - destroyed | |
private volatile boolean reading; | |
private volatile Timeout readerIdleTimeout; | |
private volatile long lastReadTime; | |
private boolean firstReaderIdleEvent = true; | |
private volatile Timeout writerIdleTimeout; | |
/** | |
* 默认为秒 | |
*/ | |
public void initTimer(HashedWheelTimer timer, int readerIdleTimeSeconds, int writerIdleTimeSeconds) { | |
initTimer(timer, readerIdleTimeSeconds, writerIdleTimeSeconds, TimeUnit.SECONDS); | |
} | |
public void initTimer(HashedWheelTimer timer, long readerIdleTime, long writerIdleTime, TimeUnit unit) { | |
Preconditions.checkNotNull(timer, "timer can't be null"); | |
if (unit == null) { | |
throw new NullPointerException("unit"); | |
} | |
this.timer = timer; | |
if (readerIdleTime <= 0L) { | |
readerIdleTimeMillis = 0L; | |
} else { | |
readerIdleTimeMillis = Math.max(unit.toMillis(readerIdleTime), MIN_TIMEOUT_MILLIS); | |
} | |
if (writerIdleTime <= 0L) { | |
writerIdleTimeMillis = 0L; | |
} else { | |
writerIdleTimeMillis = Math.max(unit.toMillis(writerIdleTime), MIN_TIMEOUT_MILLIS); | |
} | |
} | |
/** | |
* 读取超时准备释放资源 | |
*/ | |
public abstract void alreadyTimerOut(); | |
/** | |
* 改进行写了 | |
*/ | |
public abstract void timeToWrite(); | |
/** | |
* 开启计时 | |
*/ | |
public void startTimer() { | |
initialize(); | |
} | |
/** | |
* 关闭计时 | |
*/ | |
public void stopTimer() { | |
destroy(); | |
} | |
/** | |
* 现在开始读取数据 | |
*/ | |
public void nowActiveReadingTimer() { | |
if (readerIdleTimeMillis > 0) { | |
firstReaderIdleEvent = true; | |
reading = true; | |
} | |
// 读取技术 | |
this.readingFinish(); | |
} | |
/** | |
* 读取结束 todo 待优化 | |
*/ | |
private void readingFinish() { | |
if (readerIdleTimeMillis > 0) { | |
lastReadTime = SKTools.getNowTimeStamp(); | |
reading = false; | |
} | |
} | |
/** | |
* 初始化 | |
*/ | |
private void initialize() { | |
switch (state) { | |
case 1: | |
case 2: | |
return; | |
} | |
state = 1; | |
lastReadTime = SystemClock.now(); | |
if (readerIdleTimeMillis > 0) { | |
readerIdleTimeout = timer.newTimeout( | |
new ReaderIdleTimeoutTask(this), | |
readerIdleTimeMillis, TimeUnit.MILLISECONDS); | |
} | |
if (writerIdleTimeMillis > 0) { | |
writerIdleTimeout = timer.newTimeout(new WriterIdleTimeoutTask(this), writerIdleTimeMillis, TimeUnit.MILLISECONDS); | |
} | |
} | |
/** | |
* 销毁timer | |
*/ | |
private void destroy() { | |
state = 2; | |
if (readerIdleTimeout != null) { | |
readerIdleTimeout.cancel(); | |
readerIdleTimeout = null; | |
} | |
if (writerIdleTimeout != null) { | |
writerIdleTimeout.cancel(); | |
writerIdleTimeout = null; | |
} | |
} | |
/** | |
* 操作超时 | |
*/ | |
private final class ReaderIdleTimeoutTask implements TimerTask { | |
private final AbsTimerItem timerItem; | |
ReaderIdleTimeoutTask(AbsTimerItem timerItem) { | |
this.timerItem = timerItem; | |
} | |
@Override | |
public void run(Timeout timeout) throws Exception { | |
if (timeout.isCancelled()) { | |
return; | |
} | |
long lastReadTime = AbsTimerItem.this.lastReadTime; | |
long nextDelay = readerIdleTimeMillis; | |
if (!reading) { | |
nextDelay -= SystemClock.now() - lastReadTime; | |
} | |
if (nextDelay <= 0) { | |
// Reader is idle - set a new timeout and notify the callback. | |
readerIdleTimeout = timer.newTimeout(this, readerIdleTimeMillis, TimeUnit.MILLISECONDS); | |
try { | |
// | |
if (firstReaderIdleEvent) { | |
firstReaderIdleEvent = false; | |
// 第一次读等待读超时 | |
log.debug("第一次读等待读超时"); | |
} else { | |
// 准备 释放资源 | |
log.debug("准备 释放资源"); | |
AbsTimerItem.this.alreadyTimerOut(); | |
} | |
} catch (Throwable t) { | |
} | |
} else { | |
// Read occurred before the timeout - set a new timeout with shorter delay. | |
readerIdleTimeout = timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS); | |
} | |
} | |
} | |
/** | |
* 对写进行判断 | |
*/ | |
private final class WriterIdleTimeoutTask implements TimerTask { | |
private final AbsTimerItem timerItem; | |
WriterIdleTimeoutTask(AbsTimerItem timerItem) { | |
this.timerItem = timerItem; | |
} | |
@Override | |
public void run(Timeout timeout) throws Exception { | |
if (timeout.isCancelled()) { | |
return; | |
} | |
// 时间到了 直接进行下次 | |
AbsTimerItem.this.timeToWrite(); | |
writerIdleTimeout = timer.newTimeout(this, writerIdleTimeMillis, TimeUnit.MILLISECONDS); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment