synchronized与lock,哪个效率更高
Java在一开始就提供了synchronized关键字,用于多线程之间的同步。它使用简便,不会出现拿锁之后不归还的情况,可以避免一些编程错误。
而jdk5时提供的concurrent包里,有一个Lock接口以及它的实现类:ReentrantLock。这个类提供了更灵活的控制以及更强大的功能。
如果单从性能方面考虑,两个哪个更高效呢?
首先是单线程的加锁情况,见以下代码:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class SynLockTest {
public static void main(String[] args) {
long value = 0;
int MAX = 10000000;
Lock lock = new ReentrantLock();
long start = System.nanoTime();
for (int i = 0; i < MAX; i++) {
synchronized (new Object()) {
value = value + 1;
}
}
long end = System.nanoTime();
System.out.println("synchronized cost: " + (end – start)/1000000 + "ms");start = System.nanoTime();
for (int i = 0; i < MAX; i++) {
lock.lock();
try {
value = value + 1;
} finally {
lock.unlock();
}
}
end = System.nanoTime();
System.out.println("lock cost: " + (end – start) + "ns");
}
}
结果如下:
synchronized cost: 405ms
lock cost: 479ms
可见Lock的运行时间比synchronized略大。可以推测java编译器为synchronized做了特别优化。
再考虑多线程情况:
public class SynLockTest {
static class SynRunner implements Runnable {
private long v = 0;@Override
public synchronized void run() {
v = v + 1;
}
}static class LockRunner implements Runnable {
private ReentrantLock lock = new ReentrantLock();
private long v = 0;@Override
public void run() {
lock.lock();
try {
v = v + 1;
} finally {
lock.unlock();
}
}}
static class Tester {
private AtomicLong runCount = new AtomicLong(0);
private AtomicLong start = new AtomicLong();
private AtomicLong end = new AtomicLong();public Tester(final Runnable runner, int threadCount) {
final ExecutorService pool = Executors.newFixedThreadPool(threadCount);
Runnable task = new Runnable() {
@Override
public void run() {
while (true) {
runner.run();
long count = runCount.incrementAndGet();
if (count == 1) {
start.set(System.nanoTime());
} else if (count >= 10000000) {
if (count == 10000000) {
end.set(System.nanoTime());
System.out.println(runner.getClass().getSimpleName() + ", cost: "
+ (end.longValue() – start.longValue())/1000000 + "ms"); }
pool.shutdown();
return;
}
}
}
};
for (int i = 0; i < threadCount; i++) {
pool.submit(task);
}
}
}public static void main(String[] args) {
new Tester(new SynRunner(), 1);
new Tester(new LockRunner(), 1);
}}
现在测试不同线程下的表现(时间单位ms):
1 | 10 | 50 | 100 | 500 | 1000 | 5000 | |
synchronized | 542 | 4894 | 4667 | 4700 | 5151 | 5156 | 5178 |
lock | 838 | 1211 | 821 | 847 | 851 | 1211 | 1241 |
可以看到,在多线程环境并存在大量竞争的情况下,synchronized的用时迅速上升,而lock却依然保存不变或增加很少。
Lock是用CAS来实现的
JDK 1.6以上synchronized也改用CAS来实现了,所以两者性能差不多
Lock提供的功能丰富点,synchronized的使用简单点
synchronized与lock,哪个效率更高的更多相关文章
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->WinForm版本新增新的角色授权管理界面效率更高、更规范
角色授权管理模块主要是对角色的相应权限进行集中设置.在角色权限管理模块中,管理员可以添加或移除指定角色所包含的用户.可以分配或授予指定角色的模块(菜单)的访问权限.可以收回或分配指定角色的操作(功能) ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->Web版本新增新的角色授权管理界面效率更高、更规范
角色授权管理模块主要是对角色的相应权限进行集中设置.在角色权限管理模块中,管理员可以添加或移除指定角色所包含的用户.可以分配或授予指定角色的模块(菜单)的访问权限.可以收回或分配指定角色的操作(功能) ...
- Spring AOP中的JDK和CGLib动态代理哪个效率更高?
一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...
- MySQL select * 和把所有的字段都列出来,哪个效率更高?
MySQL select * 和把所有的字段都列出来,哪个效率更高 答案是:如何,都不推荐使用 SELECT * FROM (1)SELECT *,需要数据库先 Query Table Metadat ...
- Http请求封装(对HttpClient类的进一步封装,使之调用更方便。另外,此类管理唯一的HttpClient对象,支持线程池调用,效率更高)
package com.ad.ssp.engine.common; import java.io.IOException; import java.util.ArrayList; import jav ...
- 在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢
在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢
- 取代 Mybatis Generator,这款代码生成神器配置更简单,开发效率更高!
作为一名 Java 后端开发,日常工作中免不了要生成数据库表对应的持久化对象 PO,操作数据库的接口 DAO,以及 CRUD 的 XML,也就是 mapper. Mybatis Generator 是 ...
- 数据库查询SQL语句的时候如何写会效率更高?
引言 以前刚开始做项目的时候,开发经验尚浅,遇到问题需求只要把结果查询出来就行,至于查询的效率可能就没有太多考虑,数据少的时候还好,数据一多,效率问题就显现出来了.每次遇到查询比较慢时,项目经理就会问 ...
- Java分布式唯一ID生成方案——比UUID效率更高的生成id工具类
package com.xinyartech.erp.core.util; import java.lang.management.ManagementFactory; import java.net ...
- i++与++i哪个效率更高
简单的比较前缀自增运算符和后缀自增运算符的效率是片面的, 因为存在很多因素影响这个问题的答案. 首先考虑内建数据类型的情况: 如果自增运算表达式的结果没有被使用, 而是仅仅简单地用于增加一元操作数, ...
随机推荐
- BZOJ囤题计划
决定做一些题,学习jry,开坑(其实是填坑) 大概会刷的很慢,大家别鄙视我..欢迎鄙视 果然慢出翔了,还是填完吧.. 现在做了: 11 [2338][HNOI2011]数矩形 枚举对角线暴力水过,所有 ...
- 【LOJ】#2057. 「TJOI / HEOI2016」游戏
题解 我并不会做,我觉得很像网络流但是毫无建图思路 我猜了个贪心,写了一下--啥过了90分?!这数据是有多水啊.. 哦又是行列拆点 不过要按照'#'进行拆点,也就是一段横着的区间只能放一个炸弹,一段竖 ...
- 【LOJ】#2054. 「TJOI / HEOI2016」树
题解 一写过一交A的水题 只要求一个dfs序,新加一个标记在子树所在的区间上覆盖上该点,维护深度最大的答案 代码 #include <bits/stdc++.h> #define ente ...
- CF17E Palisection 差分+manacher算法
题目大意: 给定一个串$S$,询问有多少对相交的回文子串 直接做的办法: 我们先考虑求出以$i$为结尾的串的数量,这个很好统计 之后,我们再求出所有包含了点$i$的回文串的数目 这个相当于在$i$的左 ...
- 2017-2018-1 JAVA实验站 第八周作业
2017-2018-1 JAVA实验站 第八周作业 详情请见团队博客
- linux下elasticsearch安装教程
centos 7.5安装 elasticsearch 第一步,安装elasticsearch需要Java8 首先使用 yum list installed | grep java 查看安装的Java版 ...
- 删除JBOSS eap4.3下的jmx-console、web-console、ws-console、status服务
来源:http://iffiffj.iteye.com/blog/1404148 把下面代码保存为BAT文件,并放到JBOSS节点中运行. @echo off set HOME=%~dp0 set j ...
- bzoj 3668 数位DP
收获: 1.如果有很多位操作,并且不包含+-×/等高级运算,那么可以一位一位考虑,如果求一个最优解,可以尝试逐位确定,这道题因为原始攻击值有范围,那么就需要数位DP. /*************** ...
- 拆分Cocos2dx渲染部分代码
纹理实现 思想 这个是Cocos2dx的渲染部分的最基本的实现,被我拆分到mac上,但是并不是用的EGLContext,而是搭配glfw,还有soil第三方图形库. 实现 // // main.cpp ...
- Hihocoder #1081 最短路径一 dijkstra
#1081 : 最短路径·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的早上,小Hi和小Ho在经历了一个小时的争论后,终于决定了如何度过这样有意义的一天—— ...