Reduce synchronization overhead in HashedWheelTimer.start/stop()
This commit is contained in:
parent
b75ab6171c
commit
543cb17acd
@ -23,7 +23,6 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
@ -90,7 +89,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
|
|
||||||
private final Worker worker = new Worker();
|
private final Worker worker = new Worker();
|
||||||
final Thread workerThread;
|
final Thread workerThread;
|
||||||
final AtomicBoolean shutdown = new AtomicBoolean();
|
final AtomicInteger workerState = new AtomicInteger(); // 0 - init, 1 - started, 2 - shut down
|
||||||
|
|
||||||
private final long roundDuration;
|
private final long roundDuration;
|
||||||
final long tickDuration;
|
final long tickDuration;
|
||||||
@ -257,17 +256,23 @@ public class HashedWheelTimer implements Timer {
|
|||||||
* @throws IllegalStateException if this timer has been
|
* @throws IllegalStateException if this timer has been
|
||||||
* {@linkplain #stop() stopped} already
|
* {@linkplain #stop() stopped} already
|
||||||
*/
|
*/
|
||||||
public synchronized void start() {
|
public void start() {
|
||||||
if (shutdown.get()) {
|
switch (workerState.get()) {
|
||||||
throw new IllegalStateException("cannot be started once stopped");
|
case 0:
|
||||||
}
|
if (workerState.compareAndSet(0, 1)) {
|
||||||
|
|
||||||
if (!workerThread.isAlive()) {
|
|
||||||
workerThread.start();
|
workerThread.start();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
throw new IllegalStateException("cannot be started once stopped");
|
||||||
|
default:
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Set<Timeout> stop() {
|
public Set<Timeout> stop() {
|
||||||
if (Thread.currentThread() == workerThread) {
|
if (Thread.currentThread() == workerThread) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
HashedWheelTimer.class.getSimpleName() +
|
HashedWheelTimer.class.getSimpleName() +
|
||||||
@ -275,7 +280,9 @@ public class HashedWheelTimer implements Timer {
|
|||||||
TimerTask.class.getSimpleName());
|
TimerTask.class.getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shutdown.compareAndSet(false, true)) {
|
if (!workerState.compareAndSet(1, 2)) {
|
||||||
|
// workerState can be 0 or 2 at this moment - let it always be 2.
|
||||||
|
workerState.set(2);
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,9 +321,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
throw new NullPointerException("unit");
|
throw new NullPointerException("unit");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!workerThread.isAlive()) {
|
|
||||||
start();
|
start();
|
||||||
}
|
|
||||||
|
|
||||||
delay = unit.toMillis(delay);
|
delay = unit.toMillis(delay);
|
||||||
HashedWheelTimeout timeout = new HashedWheelTimeout(task, currentTime + delay);
|
HashedWheelTimeout timeout = new HashedWheelTimeout(task, currentTime + delay);
|
||||||
@ -369,7 +374,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
tick = 1;
|
tick = 1;
|
||||||
|
|
||||||
while (!shutdown.get()) {
|
while (workerState.get() == 1) {
|
||||||
final long deadline = waitForNextTick();
|
final long deadline = waitForNextTick();
|
||||||
if (deadline > 0) {
|
if (deadline > 0) {
|
||||||
fetchExpiredTimeouts(expiredTimeouts, deadline);
|
fetchExpiredTimeouts(expiredTimeouts, deadline);
|
||||||
@ -463,7 +468,7 @@ public class HashedWheelTimer implements Timer {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(sleepTime);
|
Thread.sleep(sleepTime);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
if (shutdown.get()) {
|
if (workerState.get() != 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user