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,哪个效率更高的主要内容,如果未能解决你的问题,请参考以下文章

synchronized 与 Lock 的那点事

多个小查询与单个长查询。哪个效率更高?

Oracle 数据库 SQL效率问题,下面语句的结果一样吗?如果一样哪个效率更高?

[MethodImpl(MethodImplOptions.Synchronized)]lock(this)与lock(typeof(...))

JSON 解析和XML解析 哪个效率更高

同步效率差不多CAS相比synchronized没有获得更高的性能