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哪个效率更高
简单的比较前缀自增运算符和后缀自增运算符的效率是片面的, 因为存在很多因素影响这个问题的答案. 首先考虑内建数据类型的情况: 如果自增运算表达式的结果没有被使用, 而是仅仅简单地用于增加一元操作数, ...
随机推荐
- AOP实战(1)
AOP在MVC中有广泛的应用 如:IActionFilter. IAuthenticationFilter. IAuthorizationFilter.IExceptionFilter.IResult ...
- jquery图片延迟加载方案解决图片太多加载缓慢问题
当在做一个图片展示站的时候,一个页面加载的图片过多会,如果服务器的带宽跟不上,明显会感觉到页面很卡,严重的浏览器也会崩溃,所以我推荐采用即看即所得的模式,当滚动到下一屏时才进行加载图片. 注意:即便如 ...
- 【51nod】1531 树上的博弈
题解 我们发现每次决策的时候,我们可以判断某个点的决策,至少小于等于几个点或者至少大于等于几个点 我们求最大值 dp[u][1 / 0] dp[u][1]表示u这个点先手,至少大于等于几个点 dp[u ...
- spring配置文件头部配置解析(applicationContext.xml)
分享一个好的学习网站:http://how2j.cn?p=4509 相信大家对spring的配置文件应该都看的很多了,那么大家对配置文件头部的那一坨坨的东西到底是什么了解吗?下面我就把自己的一些见解和 ...
- Yii2之控制台命令篇(console)
控制台命令 Yii 中有一个拥有丰富功能的控制台,它们主要用于创建网站后台处理的任务.在项目根目录下执行相关操作,有意思的事,可以通过 yii 自带的功能,列出当前已有的命令. 1.查看当前项目控制台 ...
- Xiaoguang Tu's Home Page
Xiaoguang Tu (涂晓光): CV: Ph.D. Candidate of School of Communication and Information Engineering, Univ ...
- xshell连接linux,切换焦点,自动执行ctrl+c
这几天发现 xshell 连接 linux 的时候,无缘无故的执行了 ctrl+c,导致 执行界面 终端,比方说 ,hbase shell 执行窗口命令 ,每次切换 窗口焦点之后,就终止了.百度后 发 ...
- 异步任务 -- FutureTask
任务提交 之前在分析线程池的时候,提到过 AbstractExecutorService 的实现: public Future<?> submit(Runnable task) { if ...
- BZOJ 2115: [Wc2011] Xor 线性基 dfs
https://www.lydsy.com/JudgeOnline/problem.php?id=2115 每一条从1到n的道路都可以表示为一条从1到n的道路异或若干个环的异或值. 那么把全部的环丢到 ...
- java设计模式(四)代理模式
适用于为不同操作添加共同的额外行为.通过代理对象访问目标对象,这样可以增加对目标对象的额外操作,达到扩展目标对象功能的目的,如spring事务.AOP等. 要点:1)抽象角色:通过接口或抽象类声明真实 ...