synchronized与lock,哪个效率更高
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的使用简单点 参考技术A 不存什么效率问题,都是线程同步用到,何来效率呢
以上是关于synchronized与lock,哪个效率更高的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 数据库 SQL效率问题,下面语句的结果一样吗?如果一样哪个效率更高?
[MethodImpl(MethodImplOptions.Synchronized)]lock(this)与lock(typeof(...))