Skip to content

Commit 50e5417

Browse files
committed
Remove CAS and make state volatile
Signed-off-by: Jason Joo <[email protected]>
1 parent 33fd844 commit 50e5417

File tree

2 files changed

+39
-36
lines changed

2 files changed

+39
-36
lines changed

sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/TimeUtil.java

+13-12
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import java.util.List;
1919
import java.util.concurrent.TimeUnit;
20-
import java.util.concurrent.atomic.AtomicLong;
2120

2221
import com.alibaba.csp.sentinel.log.RecordLog;
2322
import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray;
@@ -42,6 +41,8 @@
4241
*/
4342
public final class TimeUtil implements Runnable {
4443
private static final long CHECK_INTERVAL = 3000;
44+
private static final long HITS_LOWER_BOUNDARY = 800;
45+
private static final long HITS_UPPER_BOUNDARY = 1200;
4546

4647
public static enum STATE {
4748
IDLE, PREPARE, RUNNING;
@@ -59,9 +60,12 @@ public LongAdder getReads() {
5960
private static TimeUtil INSTANCE;
6061

6162
private volatile long currentTimeMillis;
62-
private AtomicLong lastCheck = new AtomicLong();
63+
private volatile STATE state = STATE.IDLE;
64+
6365
private LeapArray<Statistic> statistics;
64-
private STATE state = STATE.IDLE;
66+
67+
// thread private variables
68+
private long lastCheck = 0;
6569

6670
static {
6771
INSTANCE = new TimeUtil();
@@ -85,6 +89,7 @@ protected WindowWrap<Statistic> resetWindowTo(WindowWrap<Statistic> windowWrap,
8589
}
8690
};
8791
this.currentTimeMillis = System.currentTimeMillis();
92+
this.lastCheck = this.currentTimeMillis;
8893
Thread daemon = new Thread(this);
8994
daemon.setDaemon(true);
9095
daemon.setName("sentinel-time-tick-thread");
@@ -155,24 +160,20 @@ public Tuple2<Long, Long> currentQps(long now) {
155160

156161
/**
157162
* Check and operate the state if necessary.
158-
* It deals concurrency.
163+
* ATTENTION: It's called in daemon thread.
159164
*/
160165
private void check() {
161166
long now = currentTime(true);
162-
long last = this.lastCheck.get();
163167
// every period
164-
if (now - last < CHECK_INTERVAL) {
165-
return;
166-
}
167-
// concurrent
168-
if (!this.lastCheck.compareAndSet(last, now)) {
168+
if (now - this.lastCheck < CHECK_INTERVAL) {
169169
return;
170170
}
171+
this.lastCheck = now;
171172
Tuple2<Long, Long> qps = currentQps(now);
172-
if (this.state == STATE.IDLE && qps.r1 > 1200) {
173+
if (this.state == STATE.IDLE && qps.r1 > HITS_UPPER_BOUNDARY) {
173174
RecordLog.info("TimeUtil switches to PREPARE for better performance, reads={}/s, writes={}/s", qps.r1, qps.r2);
174175
this.state = STATE.PREPARE;
175-
} else if (this.state == STATE.RUNNING && qps.r1 < 800) {
176+
} else if (this.state == STATE.RUNNING && qps.r1 < HITS_LOWER_BOUNDARY) {
176177
RecordLog.info("TimeUtil switches to IDLE due to not enough load, reads={}/s, writes={}/s", qps.r1, qps.r2);
177178
this.state = STATE.IDLE;
178179
}

sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/TimeUtilTest.java

+26-24
Original file line numberDiff line numberDiff line change
@@ -49,35 +49,37 @@ private void waitFor(int step, int seconds) throws InterruptedException {
4949
public void test() throws InterruptedException {
5050
final AtomicInteger delayTime = new AtomicInteger(10);
5151
final AtomicBoolean shouldShutdown = new AtomicBoolean();
52-
new Thread(new Runnable() {
53-
54-
@Override
55-
public void run() {
56-
long last = 0;
57-
while (true) {
58-
if (shouldShutdown.get()) {
59-
break;
60-
}
61-
long now = TimeUtil.currentTimeMillis();
62-
int delay = delayTime.get();
63-
if (delay < 1) {
52+
for (int i = 0; i < 10; i ++) {
53+
new Thread(new Runnable() {
54+
55+
@Override
56+
public void run() {
57+
long last = 0;
58+
while (true) {
59+
if (shouldShutdown.get()) {
60+
break;
61+
}
62+
long now = TimeUtil.currentTimeMillis();
63+
int delay = delayTime.get();
64+
if (delay < 1) {
65+
if (last > now) {
66+
System.err.println("wrong value");
67+
}
68+
last = now;
69+
continue;
70+
}
71+
try {
72+
Thread.sleep(delay);
73+
} catch (InterruptedException e) {
74+
}
6475
if (last > now) {
65-
System.err.println("wrong value");
76+
System.err.println("incorrect value");
6677
}
6778
last = now;
68-
continue;
6979
}
70-
try {
71-
Thread.sleep(delay);
72-
} catch (InterruptedException e) {
73-
}
74-
if (last > now) {
75-
System.err.println("incorrect value");
76-
}
77-
last = now;
7880
}
79-
}
80-
}).start();
81+
}).start();
82+
}
8183
Tuple2<Long, Long> qps;
8284
waitFor(1, 4);
8385
// initial state

0 commit comments

Comments
 (0)