Fixed excessive CPU consumption
This commit is contained in:
parent
3e0d1f69b0
commit
11f7606b6d
@ -155,17 +155,14 @@ public class HashedWheelTimer implements Timer {
|
|||||||
|
|
||||||
// Add the timeout to the wheel.
|
// Add the timeout to the wheel.
|
||||||
HashedWheelTimeout timeout;
|
HashedWheelTimeout timeout;
|
||||||
|
long currentTime = System.nanoTime();
|
||||||
lock.readLock().lock();
|
lock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
timeout = new HashedWheelTimeout(
|
timeout = new HashedWheelTimeout(
|
||||||
task, wheelCursor, System.nanoTime(), initialDelay);
|
task, wheelCursor, currentTime, initialDelay);
|
||||||
|
|
||||||
wheel[schedule(timeout)].add(timeout);
|
wheel[schedule(timeout)].add(timeout);
|
||||||
|
increaseActiveTimeouts();
|
||||||
// Start the worker if necessary.
|
|
||||||
if (activeTimeouts.getAndIncrement() == 0) {
|
|
||||||
executor.execute(worker);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
lock.readLock().unlock();
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
@ -173,6 +170,13 @@ public class HashedWheelTimer implements Timer {
|
|||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void increaseActiveTimeouts() {
|
||||||
|
// Start the worker if necessary.
|
||||||
|
if (activeTimeouts.getAndIncrement() == 0) {
|
||||||
|
executor.execute(worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int schedule(HashedWheelTimeout timeout) {
|
private int schedule(HashedWheelTimeout timeout) {
|
||||||
return schedule(timeout, timeout.initialDelay);
|
return schedule(timeout, timeout.initialDelay);
|
||||||
}
|
}
|
||||||
@ -217,6 +221,8 @@ public class HashedWheelTimer implements Timer {
|
|||||||
private final class Worker implements Runnable {
|
private final class Worker implements Runnable {
|
||||||
|
|
||||||
private volatile long threadSafeStartTime;
|
private volatile long threadSafeStartTime;
|
||||||
|
private volatile long threadSafeTick;
|
||||||
|
private long startTime;
|
||||||
private long tick;
|
private long tick;
|
||||||
|
|
||||||
Worker() {
|
Worker() {
|
||||||
@ -227,15 +233,24 @@ public class HashedWheelTimer implements Timer {
|
|||||||
List<HashedWheelTimeout> expiredTimeouts =
|
List<HashedWheelTimeout> expiredTimeouts =
|
||||||
new ArrayList<HashedWheelTimeout>();
|
new ArrayList<HashedWheelTimeout>();
|
||||||
|
|
||||||
long startTime = threadSafeStartTime;
|
startTime = threadSafeStartTime;
|
||||||
tick = 1;
|
tick = threadSafeTick;
|
||||||
|
if (startTime == 0) {
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
tick = 1;
|
||||||
|
}
|
||||||
|
|
||||||
boolean continueTheLoop;
|
try {
|
||||||
do {
|
boolean continueTheLoop;
|
||||||
startTime = waitForNextTick(startTime);
|
do {
|
||||||
continueTheLoop = fetchExpiredTimeouts(expiredTimeouts);
|
startTime = waitForNextTick();
|
||||||
notifyExpiredTimeouts(expiredTimeouts);
|
continueTheLoop = fetchExpiredTimeouts(expiredTimeouts);
|
||||||
} while (continueTheLoop && !ExecutorUtil.isShutdown(executor));
|
notifyExpiredTimeouts(expiredTimeouts);
|
||||||
|
} while (continueTheLoop && !ExecutorUtil.isShutdown(executor));
|
||||||
|
} finally{
|
||||||
|
threadSafeStartTime = startTime;
|
||||||
|
threadSafeTick = tick;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fetchExpiredTimeouts(
|
private boolean fetchExpiredTimeouts(
|
||||||
@ -277,27 +292,24 @@ public class HashedWheelTimer implements Timer {
|
|||||||
ReusableIterator<HashedWheelTimeout> i) {
|
ReusableIterator<HashedWheelTimeout> i) {
|
||||||
|
|
||||||
long currentTime = System.nanoTime();
|
long currentTime = System.nanoTime();
|
||||||
boolean notEmpty = i.hasNext();
|
i.rewind();
|
||||||
if (notEmpty) {
|
while (i.hasNext()) {
|
||||||
do {
|
HashedWheelTimeout timeout = i.next();
|
||||||
HashedWheelTimeout timeout = i.next();
|
synchronized (timeout) {
|
||||||
synchronized (timeout) {
|
if (timeout.remainingRounds <= 0) {
|
||||||
if (timeout.remainingRounds <= 0) {
|
if (timeout.deadline <= currentTime) {
|
||||||
if (timeout.deadline <= currentTime) {
|
i.remove();
|
||||||
i.remove();
|
expiredTimeouts.add(timeout);
|
||||||
expiredTimeouts.add(timeout);
|
activeTimeouts.getAndDecrement();
|
||||||
activeTimeouts.getAndDecrement();
|
|
||||||
} else {
|
|
||||||
// A rare case where a timeout is put for the next
|
|
||||||
// round: just wait for the next round.
|
|
||||||
timeout.slippedRounds ++;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
timeout.remainingRounds --;
|
// A rare case where a timeout is put for the next
|
||||||
|
// round: just wait for the next round.
|
||||||
|
timeout.slippedRounds ++;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
timeout.remainingRounds --;
|
||||||
}
|
}
|
||||||
} while (i.hasNext());
|
}
|
||||||
i.rewind();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +324,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
expiredTimeouts.clear();
|
expiredTimeouts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long waitForNextTick(long startTime) {
|
private long waitForNextTick() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
final long currentTime = System.nanoTime();
|
final long currentTime = System.nanoTime();
|
||||||
final long sleepTime = tickDuration * tick - (currentTime - startTime);
|
final long sleepTime = tickDuration * tick - (currentTime - startTime);
|
||||||
@ -411,11 +423,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wheel[newStopIndex].add(this)) {
|
if (wheel[newStopIndex].add(this)) {
|
||||||
|
increaseActiveTimeouts();
|
||||||
// Start the worker if necessary.
|
|
||||||
if (activeTimeouts.getAndIncrement() == 0) {
|
|
||||||
executor.execute(worker);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
extensionCount ++;
|
extensionCount ++;
|
||||||
@ -514,12 +522,12 @@ public class HashedWheelTimer implements Timer {
|
|||||||
for (int i = 0; i < 1; i ++) {
|
for (int i = 0; i < 1; i ++) {
|
||||||
timer.newTimeout(new TimerTask() {
|
timer.newTimeout(new TimerTask() {
|
||||||
public void run(Timeout timeout) throws Exception {
|
public void run(Timeout timeout) throws Exception {
|
||||||
//System.out.println(Thread.currentThread().getName() + ": " + timeout.getExtensionCount() + ": " + timeout);
|
System.out.println(Thread.currentThread().getName() + ": " + timeout.getExtensionCount() + ": " + timeout);
|
||||||
timeout.extend();
|
timeout.extend();
|
||||||
int c = e.getActiveCount();
|
int c = e.getActiveCount();
|
||||||
if (c > 1) {
|
// if (c > 1) {
|
||||||
System.out.println(System.currentTimeMillis() + ": " + c);
|
// System.out.println(System.currentTimeMillis() + ": " + c);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}, 100, TimeUnit.MILLISECONDS);
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user