Java18 sychronized 锁消除和锁膨胀 代码复现
锁消除和锁膨胀是JVM在运行时对同步锁的优化策略。在某些情况下,JVM会自动优化同步锁的使用,通过消除不必要的同步锁来提高程序的执行效率。而在另一些情况下,JVM会将不可消除的同步锁转换为重量级锁,以保证多线程的正确性。
下面是一个简单的示例代码,用来演示锁消除和锁膨胀的情况:
public class LockExample {
private int count = 0;
public void increment() {
synchronized (this) { // 同步锁
count++;
}
}
public int getCount() {
synchronized (this) { // 同步锁
return count;
}
}
public static void main(String[] args) {
LockExample example = new LockExample();
// 多个线程同时对count进行累加操作
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
example.increment();
}
}).start();
}
// 主线程等待所有子线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + example.getCount());
}
}
在上面的代码中,我们使用了一个简单的计数器示例。每个线程都会对计数器进行1000次的累加操作。运行这段代码,可以得到正确的计数结果。
在这个示例中,由于每个线程都是对同一个对象的同步锁进行操作,JVM可以进行锁消除的优化,将不必要的同步锁消除掉,从而提高程序的性能。
但是,如果我们对LockExample类进行一些修改,使得每个线程对不同的对象进行同步锁的操作,JVM就无法进行锁消除的优化了,而会将同步锁转换为重量级锁,即锁膨胀。下面是修改后的代码:
public class LockExample {
private int count = 0;
public void increment() {
synchronized (new Object()) { // 同步锁
count++;
}
}
public int getCount() {
synchronized (new Object()) { // 同步锁
return count;
}
}
public static void main(String[] args) {
LockExample example = new LockExample();
// 多个线程同时对count进行累加操作
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
example.increment();
}
}).start();
}
// 主线程等待所有子线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + example.getCount());
}
}
运行这段代码,可以看到程序仍然能够得到正确的计数结果,但是性能可能会有所下降,因为每个线程都会对不同的对象进行同步锁的操作,导致锁膨胀的发生。
需要注意的是,锁消除和锁膨胀是由JVM自动进行的优化策略,开发者无法直接控制和干预。在实际开发中,应该尽量避免不必要的同步锁的使用,以提高程序的性能
原文地址: http://www.cveoy.top/t/topic/iWby 著作权归作者所有。请勿转载和采集!