System.currentTimeMillis()

测试代码

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
public static void main(String[] args) {
long start = System.nanoTime();
singleThread(100);
System.out.println("single: " + (System.nanoTime() - start));
start = System.nanoTime();
multiThread(100);
System.out.println("multi: " + (System.nanoTime() - start));
}

public static void singleThread(int size) {
for (int i = 0; i < size; i++) {
System.currentTimeMillis();
}
}

public static void multiThread(int size) {
CountDownLatch latch = new CountDownLatch(size);
for (int i = 0; i < size; i++) {
new Thread(() -> {
try {
System.currentTimeMillis();
} finally {
latch.countDown();
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

分析

System.currentTimeMillis()调用会与系统交互,频繁访问或者高并发会造成严重的争用

结果

1
2
single: 17727
multi: 58580004

解决思路

  • 创建一个类,在类中维护一个线程,定时去同步

    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
    public class CurrentTimeMillisClock {
    private volatile long now;

    private CurrentTimeMillisClock() {
    this.now = System.currentTimeMillis();
    scheduleTick();
    }

    private void scheduleTick() {
    new ScheduledThreadPoolExecutor(1, runnable -> {
    Thread thread = new Thread(runnable, "current-time-millis");
    thread.setDaemon(true);
    return thread;
    }).scheduleAtFixedRate(() -> {
    now = System.currentTimeMillis();
    }, 1, 1, TimeUnit.MILLISECONDS);
    }

    public long now() {
    return now;
    }

    public static CurrentTimeMillisClock getInstance() {
    return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
    private static final CurrentTimeMillisClock INSTANCE = new
    CurrentTimeMillisClock();
    }
    }