同步锁在多线程编程中是保证线程安全的重要工具,其性能开销一直是不可忽视的存在。
(一)性能验证说明
为了直观说明我们可以直接先准备两个Java代码用例,我们通过高并发环境下的计数器递增操作来对比使用同步锁和不使用同步锁的性能差异。
1. 使用同步锁的代码示例
使用ReentrantLock来保护对共享资源(counter)的访问,确保同一时间只有一个线程可以对计数器进行操作。具体代码如下:
package org.zyf.javabasic.thread.lock.opti;
import java.util.concurrent.locks.ReentrantLock;
/**
* @program: zyfboot-javabasic
* @description: 使用了ReentrantLock来保护对共享资源(counter)的访问,确保同一时间只有一个线程可以对计数器进行操作。
* @author: zhangyanfeng
* @create: 2024-06-05 22:54
**/
public class SyncLockExample {
private static int counter = 0;
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
long startTime = System.currentTimeMillis();
Thread[] threads = new Thread[100];
for (int i = 0; i < 100; i++) {
threads[i] = new Thread(new IncrementWithLock());
threads[i].start();
}
for (Thread thread : threads) {
thread.join();
}
long endTime = System.currentTimeMillis();
System.out.println("Time with lock: " + (endTime - startTime) + " ms");
}
static class IncrementWithLock implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000000; i++) {
lock.lock();
try {
counter++;
} finally {
lock.unlock();
}
}
}
}
}
2. 不使用同步锁的代码示例
不使用任何同步机制,直接操作共享资源。具体代码如下:
package org.zyf.javabasic.thread.lock.opti;
/**
* @program: zyfboot-javabasic
* @description: 不使用任何同步机制,直接操作共享资源。
* @author: zhangyanfeng
* @create: 2024-06-05 22:55
**/
public class NoSyncLockExample {
private static int counter = 0;
public static void main(String[] args) throws InterruptedException {
long startTime = System.currentTimeMillis();
Thread[] threads = new Thread[100];
for (int i = 0; i < 100; i++) {
threads[i] = new Thread(new IncrementWithoutLock());
threads[i].start();
}
for (Thread thread : threads) {
thread.join();
}
long endTime = System.currentTimeMillis();
System.out.println("Time without lock: " + (endTime - startTime) + " ms");
}
static class IncrementWithoutLock implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000000; i++) {
counter++;
}
}
}
}
3. 结果与讨论
运行以上代码,我当前的机器上可以直观的看到
使用同步锁的时间: 1314 ms
不使用同步锁的时间: 20 ms
从结果中可以明显看出,同步锁会带来显著的性能开销。同步锁的存在增加了线程间的等待时间和上下文切换的开销,从而降低了程序的整体运行效率。所以在使用锁时,对锁的优化使用是必不可少的。