0%

java | synchronized 锁消除

锁优化时 JIT 「即时编译器」自带的。打成 jar 包后,自动启动。

代码

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
package com.redisc;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

@Data
class User {
}

@Slf4j(topic = "c.Test")
public class Test {
public static void main(String[] args) throws Exception {
User user1 = new User();
int t = 0;
long start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
t++;
}
log.debug("{}", System.nanoTime() - start);
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
synchronized (user1) {

t++;
}
}
log.debug("{}", System.nanoTime() - start);
}
}

打成 jar 包

输出

1
2
13:15:07.528 [main] DEBUG c.Test - 38901618
13:15:07.553 [main] DEBUG c.Test - 21990764

为什么后面加锁反而更快了,我个人认为是 JIT 在初次运行的时候,还没有优化好,等运行到加锁代码的时候,已经优化好了。

测试一下,代码改成,并打包

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
package com.redisc;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

@Data
class User {
}

@Slf4j(topic = "c.Test")
public class Test {
public static void main(String[] args) throws Exception {
User user1 = new User();
int t = 0;
long start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
t++;
}
log.debug("{}", System.nanoTime() - start);
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
synchronized (user1) {

t++;
}
}
log.debug("{}", System.nanoTime() - start);
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
synchronized (user1) {

t++;
}
}
log.debug("{}", System.nanoTime() - start);
}
}

输出

1
2
3
13:17:13.907 [main] DEBUG c.Test - 39486256
13:17:13.931 [main] DEBUG c.Test - 21059873
13:17:13.953 [main] DEBUG c.Test - 21436095

在 IDEA 中运行

1
2
13:15:44.900 [main] DEBUG c.Test - 2505509
13:15:45.084 [main] DEBUG c.Test - 179604356
请我喝杯咖啡吧~