Java里,synchronized和lock效率的简单比较
通常而言,我们可能都倾向于使用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
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
react的状态管理库 Mobx