Java里,synchronized和lock效率的简单比较

您所在的位置:网站首页 c线程锁的效率对比 Java里,synchronized和lock效率的简单比较

Java里,synchronized和lock效率的简单比较

2023-09-05 20:15| 来源: 网络整理| 查看: 265

通常而言,我们可能都倾向于使用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

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3