通常而言,我们可能都倾向于使用Lock来实现线程的同步,但是synchronized和lock究竟哪个效率高呢?
下面我们来做一个简单的对比实验,只比较最基础的部分,暂时不涉及等待和唤醒。
测试环境: JDK1.8
OS: win10 64bit
测试代码:
public class T {
Lock lock = new ReentrantLock();
public synchronized void f() {
}
public void g() {
lock.lock();
lock.unlock();
}
public static void main(String[] args) throws InterruptedException {
int count = 1000000000, i;
long time = 0;
T t = new T();
time = System.currentTimeMillis();
for (i = 0; i < count; i ++)
t.f();
System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (i = 0; i < count; i ++)
t.g();
System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (i = 0; i < count; i ++)
t.f();
System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (i = 0; i < count; i ++)
t.g();
System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (i = 0; i < count; i ++)
t.f();
System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (i = 0; i < count; i ++)
t.g();
System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
}
}
测试结果:
Sync Time:4442
Lock Time:10824
Sync Time:2155
Lock Time:9592
Sync Time:2331
Lock Time:9550
结论:synchronized的效率远远高于lock操作,而且随着实验的重复,synchronized会进行优化,效率大概是Lock的2-4倍。
另类结论: 从循环的次数可以看出,无论是synchronized或者Lock,本身的效率已经非常高了,10亿次的操作,只需要10秒不到的时间,加锁一次大概需要10ns而已,synchronized大概只需要2ns。所以,其差距基本上也可以忽略不计了。
下面我们来进行更复杂一点的测试,以考验多线程环境下的效率。
测试代码:
public class T {
Lock lock = new ReentrantLock();
public synchronized void f() {
try {
Thread.sleep(1);
} catch (Exception e) {
}
finally {
}
}
public void g() {
lock.lock();
try {
Thread.sleep(1);
} catch (Exception e) {
}
finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
int count = 10000, i;
long time = 0;
ExecutorService workers = null;
T t = new T();
time = System.currentTimeMillis();
workers = Executors.newFixedThreadPool(10);
for (i = 0; i < count; i ++)
workers.submit(() -> t.f());
workers.shutdown();
workers.awaitTermination(100000, TimeUnit.DAYS);
System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
workers = Executors.newFixedThreadPool(10);
for (i = 0; i < count; i ++)
workers.submit(() -> t.g());
workers.shutdown();
workers.awaitTermination(100000, TimeUnit.DAYS);
System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
workers = Executors.newFixedThreadPool(10);
for (i = 0; i < count; i ++)
workers.submit(() -> t.f());
workers.shutdown();
workers.awaitTermination(100000, TimeUnit.DAYS);
System.out.println("Sync Time:" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
workers = Executors.newFixedThreadPool(10);
for (i = 0; i < count; i ++)
workers.submit(() -> t.g());
workers.shutdown();
workers.awaitTermination(100000, TimeUnit.DAYS);
System.out.println("Lock Time:" + (System.currentTimeMillis() - time));
}
}
测试结果:
Sync Time:10028
Lock Time:7511
Sync Time:6938
Lock Time:4332
结论:synchronized在初始化时需要耗费较多事件,总的来说,多线程环境下Lock的效率更高一些。
这和网络上的结论基本是一致的,即如果竞争复杂,则使用Lock,如果竞争简单,则可使用synchronized
————————————————
版权声明:本文为CSDN博主「RedGuest」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/RedGuest/article/details/111935138