WangHan
2024-09-12 d5855a4926926698b740bc6c7ba489de47adb68b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package tech.powerjob.server.test;
 
import org.junit.jupiter.api.Test;
import tech.powerjob.server.common.timewheel.HashedWheelTimer;
import tech.powerjob.server.common.timewheel.TimerFuture;
import tech.powerjob.server.common.timewheel.TimerTask;
import tech.powerjob.server.common.timewheel.holder.InstanceTimeWheelService;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
 
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
 
/**
 * 时间轮测试
 *
 * @author tjq
 * @since 2020/11/28
 */
@Slf4j
public class HashedWheelTimerTest {
 
    @Test
    public void testHashedWheelTimer() throws Exception {
 
        HashedWheelTimer timer = new HashedWheelTimer(1, 1024, 32);
        List<TimerFuture> futures = Lists.newLinkedList();
 
        for (int i = 0; i < 10; i++) {
 
            String name = "Task" + i;
            long nowMS = System.currentTimeMillis();
            int delayMS = ThreadLocalRandom.current().nextInt(60000);
            long targetTime = delayMS + nowMS;
 
            TimerTask timerTask = () -> {
                System.out.println("============= " + name + "============= ");
                System.out.println("ThreadInfo:" + Thread.currentThread().getName());
                System.out.println("expectTime:" + targetTime);;
                System.out.println("currentTime:" + System.currentTimeMillis());
                System.out.println("deviation:" + (System.currentTimeMillis() - targetTime));
                System.out.println("============= " + name + "============= ");
            };
            futures.add(timer.schedule(timerTask, delayMS, TimeUnit.MILLISECONDS));
        }
 
        // 随机取消
        futures.forEach(future -> {
 
            int x = ThreadLocalRandom.current().nextInt(2);
            if (x == 1) {
                future.cancel();
            }
 
        });
 
        Thread.sleep(10);
 
        // 关闭
        System.out.println(timer.stop().size());
        System.out.println("Finished!");
 
        Thread.sleep(27);
    }
 
    @Test
    public void testPerformance() throws Exception {
        Stopwatch sw = Stopwatch.createStarted();
        for (long i = 0; i < 10; i++) {
            long delay = ThreadLocalRandom.current().nextLong(100, 120000);
            long expect = System.currentTimeMillis() + delay;
            InstanceTimeWheelService.schedule(i, delay, () -> {
               log.info("[Performance] deviation:{}", (System.currentTimeMillis() - expect));
            });
        }
        log.info("[Performance] insert cost: {}", sw);
 
        Thread.sleep(90);
    }
 
    @Test
    public void testLongDelayTask() throws Exception {
        for (long i = 0; i < 10; i++) {
            long delay = ThreadLocalRandom.current().nextLong(60000, 60000 * 3);
            long expect = System.currentTimeMillis() + delay;
            InstanceTimeWheelService.schedule(i, delay, () -> {
                log.info("[LongDelayTask] deviation: {}", (System.currentTimeMillis() - expect));
            });
        }
 
        Thread.sleep(60 * 4);
    }
 
    @Test
    public void testCancelDelayTask() throws Exception {
 
        AtomicLong executeNum = new AtomicLong();
        AtomicLong cancelNum = new AtomicLong();
        for (long i = 0; i < 10; i++) {
            long delay = ThreadLocalRandom.current().nextLong(60000, 60000 * 2);
            long expect = System.currentTimeMillis() + delay;
            InstanceTimeWheelService.schedule(i, delay, () -> {
                executeNum.incrementAndGet();
                log.info("[CancelLongDelayTask] deviation: {}", (System.currentTimeMillis() - expect));
            });
        }
 
        Thread.sleep(10);
 
        for (long i = 0; i < 10; i++) {
            boolean nextBoolean = ThreadLocalRandom.current().nextBoolean();
            if (nextBoolean) {
                continue;
            }
            boolean cancel = InstanceTimeWheelService.fetchTimerFuture(i).cancel();
            log.info("[CancelLongDelayTask] id:{},status:{}", i, cancel);
            cancelNum.incrementAndGet();
        }
 
        Thread.sleep(60 * 4);
        log.info("[CancelLongDelayTask] result -> executeNum:{},cancelNum:{}", executeNum, cancelNum);
    }
}