为什么80%的码农都做不了架构师?>>>   

为了比较一下ReentrantLock和synchronized的性能,做了一下性能测试:

得出结论:

(1)使用Lock的性能比使用synchronized关键字要提高4~5倍;

(2)使用信号量实现同步的速度大约比synchronized要慢10~20%;

(3)使用atomic包的AtomicInter速度是比Lock要快1一个数量级。

ReentrantLock 类
java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为 Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。ReentrantLock 类实现了 Lock,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。)

reentrant 锁意味着什么呢?简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放。这模仿了 synchronized 的语义;如果线程进入由线程已经拥有的监控器保护的 synchronized 块,就允许线程继续进行,当线程退出第二个(或者后续)synchronized 块的时候,不释放锁,只有线程退出它进入的监控器保护的第一个 synchronized 块时,才释放锁。

在查看清单 1 中的代码示例时,可以看到 Lock 和 synchronized 有一点明显的区别 —— lock 必须在 finally 块中释放。否则,如果受保护的代码将抛出异常,锁就有可能永远得不到释放!这一点区别看起来可能没什么,但是实际上,它极为重要。忘记在 finally 块中释放锁,可能会在程序中留下一个定时bomb,当有一天bomb爆炸时,您要花费很大力气才有找到源头在哪。而使用同步,JVM 将确保锁会获得自动释放。

Test的源码

view plaincopy to clipboardprint?
01.public abstract class Test {  
02.    protected String id;  
03.    protected CyclicBarrier barrier;  
04.    protected long count;  
05.    protected int threadNum;  
06.    protected ExecutorService executor;  
07. 
08.    public Test(String id, CyclicBarrier barrier, long count, int threadNum,  
09.            ExecutorService executor) {  
10.        this.id = id;  
11.        this.barrier = barrier;  
12.        this.count = count;  
13.        this.threadNum = threadNum;  
14.        this.executor = executor;  
15.    }  
16. 
17.    public void startTest() {  
18. 
19.        long start = System.currentTimeMillis();  
20. 
21.        for (int j = 0; j < threadNum; j++) {  
22.            executor.execute(new Thread() {  
23.                @Override 
24.                public void run() {  
25.                    for (int i = 0; i < count; i++) {  
26.                        test();  
27.                    }  
28. 
29.                    try {  
30.                        barrier.await();  
31. 
32.                    } catch (InterruptedException e) {  
33.                        e.printStackTrace();  
34.                    } catch (BrokenBarrierException e) {  
35.                        e.printStackTrace();  
36.                    }  
37.                }  
38.            });  
39.        }  
40. 
41.        try {  
42.            barrier.await();  
43.        } catch (InterruptedException e) {  
44.            e.printStackTrace();  
45.        } catch (BrokenBarrierException e) {  
46.            e.printStackTrace();  
47.        }  
48. 
49.        // 所有线程执行完成之后,才会跑到这一步  
50.        long duration = System.currentTimeMillis() - start;  
51.        System.out.println(id + " = " + duration);  
52.    }  
53. 
54.    protected abstract void test();  
55.} 
public abstract class Test {
 protected String id;
 protected CyclicBarrier barrier;
 protected long count;
 protected int threadNum;
 protected ExecutorService executor;

public Test(String id, CyclicBarrier barrier, long count, int threadNum,
   ExecutorService executor) {
  this.id = id;
  this.barrier = barrier;
  this.count = count;
  this.threadNum = threadNum;
  this.executor = executor;
 }

public void startTest() {

long start = System.currentTimeMillis();

for (int j = 0; j < threadNum; j++) {
   executor.execute(new Thread() {
    @Override
    public void run() {
     for (int i = 0; i < count; i++) {
      test();
     }

try {
      barrier.await();

} catch (InterruptedException e) {
      e.printStackTrace();
     } catch (BrokenBarrierException e) {
      e.printStackTrace();
     }
    }
   });
  }

try {
   barrier.await();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (BrokenBarrierException e) {
   e.printStackTrace();
  }

// 所有线程执行完成之后,才会跑到这一步
  long duration = System.currentTimeMillis() - start;
  System.out.println(id + " = " + duration);
 }

protected abstract void test();
}

测试类ReentreLockTest 源码

view plaincopy to clipboardprint?
01.import thread.test.Test;  
02. 
03.public class ReentreLockTest {  
04.    private static long COUNT = 1000000;  
05.    private static Lock lock = new ReentrantLock();  
06.    private static long lockCounter = 0;  
07.    private static long syncCounter = 0;  
08.    private static long semaCounter = 0;  
09.    private static AtomicLong atomicCounter = new AtomicLong(0);  
10.    private static Object syncLock = new Object();  
11.    private static Semaphore mutex = new Semaphore(1);  
12. 
13.    public static void testLock(int num, int threadCount) {  
14. 
15.    }  
16. 
17.    static long getLock() {  
18.        lock.lock();  
19.        try {  
20.            return lockCounter;  
21.        } finally {  
22.            lock.unlock();  
23.        }  
24.    }  
25. 
26.    static long getSync() {  
27.        synchronized (syncLock) {  
28.            return syncCounter;  
29.        }  
30.    }  
31. 
32.    static long getAtom() {  
33.        return atomicCounter.get();  
34.    }  
35. 
36.    static long getSemaphore() throws InterruptedException {  
37.        mutex.acquire();  
38. 
39.        try {  
40.            return semaCounter;  
41.        } finally {  
42.            mutex.release();  
43.        }  
44.    }  
45. 
46.    static long getLockInc() {  
47.        lock.lock();  
48.        try {  
49.            return ++lockCounter;  
50.        } finally {  
51.            lock.unlock();  
52.        }  
53.    }  
54. 
55.    static long getSyncInc() {  
56.        synchronized (syncLock) {  
57.            return ++syncCounter;  
58.        }  
59.    }  
60. 
61.    static long getAtomInc() {  
62.        return atomicCounter.getAndIncrement();  
63.    }  
64. 
65.    static class SemaTest extends Test {  
66. 
67.        public SemaTest(String id, CyclicBarrier barrier, long count,  
68.                int threadNum, ExecutorService executor) {  
69.            super(id, barrier, count, threadNum, executor);  
70.        }  
71. 
72.        @Override 
73.        protected void test() {  
74.            try {  
75.                getSemaphore();  
76.            } catch (InterruptedException e) {  
77.                e.printStackTrace();  
78.            }  
79.        }  
80. 
81.    }  
82. 
83.    static class LockTest extends Test {  
84. 
85.        public LockTest(String id, CyclicBarrier barrier, long count,  
86.                int threadNum, ExecutorService executor) {  
87.            super(id, barrier, count, threadNum, executor);  
88.        }  
89. 
90.        @Override 
91.        protected void test() {  
92.            getLock();  
93.        }  
94. 
95.    }  
96. 
97.    static class SyncTest extends Test {  
98. 
99.        public SyncTest(String id, CyclicBarrier barrier, long count,  
100.                int threadNum, ExecutorService executor) {  
101.            super(id, barrier, count, threadNum, executor);  
102.        }  
103. 
104.        @Override 
105.        protected void test() {  
106.            getSync();  
107.        }  
108. 
109.    }  
110. 
111.    static class AtomicTest extends Test {  
112. 
113.        public AtomicTest(String id, CyclicBarrier barrier, long count,  
114.                int threadNum, ExecutorService executor) {  
115.            super(id, barrier, count, threadNum, executor);  
116.        }  
117. 
118.        @Override 
119.        protected void test() {  
120.            getAtom();  
121.        }  
122. 
123.    }  
124. 
125.    public static void test(String id, long count, int threadNum,  
126.            ExecutorService executor) {  
127. 
128.        final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,  
129.                new Thread() {  
130. 
131.                    @Override 
132.                    public void run() {  
133. 
134.                    }  
135.                });  
136. 
137.        System.out.println("==============================");  
138.        System.out.println("count = " + count + "\t" + "Thread Count = " 
139.                + threadNum);  
140. 
141.        new LockTest("Lock ", barrier, COUNT, threadNum, executor).startTest();  
142.        new SyncTest("Sync ", barrier, COUNT, threadNum, executor).startTest();  
143.        new AtomicTest("Atom ", barrier, COUNT, threadNum, executor)  
144.                .startTest();  
145.        new SemaTest("Sema ", barrier, COUNT, threadNum, executor)  
146.                .startTest();  
147.        System.out.println("==============================");  
148.    }  
149. 
150.    public static void main(String[] args) {  
151.        for (int i = 1; i < 5; i++) {  
152.            ExecutorService executor = Executors.newFixedThreadPool(10 * i);  
153.            test("", COUNT * i, 10 * i, executor);  
154.        }  
155.    }  
156.} 
import thread.test.Test;

public class ReentreLockTest {
 private static long COUNT = 1000000;
 private static Lock lock = new ReentrantLock();
 private static long lockCounter = 0;
 private static long syncCounter = 0;
 private static long semaCounter = 0;
 private static AtomicLong atomicCounter = new AtomicLong(0);
 private static Object syncLock = new Object();
 private static Semaphore mutex = new Semaphore(1);

public static void testLock(int num, int threadCount) {

}

static long getLock() {
  lock.lock();
  try {
   return lockCounter;
  } finally {
   lock.unlock();
  }
 }

static long getSync() {
  synchronized (syncLock) {
   return syncCounter;
  }
 }

static long getAtom() {
  return atomicCounter.get();
 }

static long getSemaphore() throws InterruptedException {
  mutex.acquire();

try {
   return semaCounter;
  } finally {
   mutex.release();
  }
 }

static long getLockInc() {
  lock.lock();
  try {
   return ++lockCounter;
  } finally {
   lock.unlock();
  }
 }

static long getSyncInc() {
  synchronized (syncLock) {
   return ++syncCounter;
  }
 }

static long getAtomInc() {
  return atomicCounter.getAndIncrement();
 }

static class SemaTest extends Test {

public SemaTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }

@Override
  protected void test() {
   try {
    getSemaphore();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }

}

static class LockTest extends Test {

public LockTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }

@Override
  protected void test() {
   getLock();
  }

}

static class SyncTest extends Test {

public SyncTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }

@Override
  protected void test() {
   getSync();
  }

}

static class AtomicTest extends Test {

public AtomicTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }

@Override
  protected void test() {
   getAtom();
  }

}

public static void test(String id, long count, int threadNum,
   ExecutorService executor) {

final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,
    new Thread() {

@Override
     public void run() {

}
    });

System.out.println("==============================");
  System.out.println("count = " + count + "\t" + "Thread Count = "
    + threadNum);

new LockTest("Lock ", barrier, COUNT, threadNum, executor).startTest();
  new SyncTest("Sync ", barrier, COUNT, threadNum, executor).startTest();
  new AtomicTest("Atom ", barrier, COUNT, threadNum, executor)
    .startTest();
  new SemaTest("Sema ", barrier, COUNT, threadNum, executor)
    .startTest();
  System.out.println("==============================");
 }

public static void main(String[] args) {
  for (int i = 1; i < 5; i++) {
   ExecutorService executor = Executors.newFixedThreadPool(10 * i);
   test("", COUNT * i, 10 * i, executor);
  }
 }
}

结果

view plaincopy to clipboardprint?
01.==============================  
02.count = 1000000 Thread Count = 10  
03.Lock  = 953  
04.Sync  = 3781  
05.Atom  = 78  
06.Sema  = 4922  
07.==============================  
08.==============================  
09.count = 2000000 Thread Count = 20  
10.Lock  = 1906  
11.Sync  = 8469  
12.Atom  = 172  
13.Sema  = 9719  
14.==============================  
15.==============================  
16.count = 3000000 Thread Count = 30  
17.Lock  = 2890  
18.Sync  = 12641  
19.Atom  = 219  
20.Sema  = 15015  
21.==============================  
22.==============================  
23.count = 4000000 Thread Count = 40  
24.Lock  = 3844  
25.Sync  = 17141  
26.Atom  = 343  
27.Sema  = 19782  
28.==============================

转载于:https://my.oschina.net/digerl/blog/33282

各种同步方法性能比较(synchronized,ReentrantLock,Atomic)相关推荐

  1. synchronized,ReentrantLock解决锁冲突,脏读的问题

    最常见的秒杀系统,解决思路就是从前端.后台服务.数据库层层去掉负载,以达到平衡 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLo ...

  2. ThreadLocal、Volatile、synchronized、Atomic关键字扫盲

    前言 对于ThreadLocal.Volatile.synchronized.Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点.区别 ...

  3. 还在用Synchronized?Atomic你了解不?

    前言 只有光头才能变强 之前已经写过多线程相关的文章了,有兴趣的同学可以去了解一下: https://github.com/ZhongFuCheng3y/3y/blob/master/src/thre ...

  4. 【java】java wait 原理 synchronized ReentrantLock 唤醒顺序

    1.概述 转载:并发编程系列--wait原理的讨论(1) 学习一 网友交流 请问下,synchronized大并发的情况 下,等待区的线程entrySet和waitSet里的线程分别对 应Thread ...

  5. java高并发日志_高并发下log4j的性能瓶颈

    开篇 近期由于业务需要进行业务迁移,期间因为误设置log4j的日志级别,导致系统性能整体下降,具体表现在QPS下降明显,系统RT上升.迁移期间由于各类系统环境较原来有较大差别,因为在排查过程中也走了一 ...

  6. 高并发下log4j的性能瓶颈

    开篇  近期由于业务需要进行业务迁移,期间因为误设置log4j的日志级别,导致系统性能整体下降,具体表现在QPS下降明显,系统RT上升.迁移期间由于各类系统环境较原来有较大差别,因为在排查过程中也走了 ...

  7. 互斥同步(synchronized、Lock、ReentrantLock、ReadWriteLock、ReentrantReadWriteLock)

    互斥同步 Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问: JVM 实现的 synchronized JDK 实现的 ReentrantLock 1. synchronized sync ...

  8. Java—synchronized和ReentrantLock锁详解

    关注微信公众号:CodingTechWork,一起学习进步. 1 synchronized 1.1 synchronized介绍 synchronized机制提供了对每个对象相关的隐式监视器锁,并强制 ...

  9. 【重难点】【JUC 04】synchronized 原理、ReentrantLock 原理、synchronized 和 Lock 的对比、CAS 无锁原理

    [重难点][JUC 04]synchronized 原理.ReentrantLock 原理.synchronized 和 Lock 的对比.CAS 无锁原理 文章目录 [重难点][JUC 04]syn ...

最新文章

  1. WKWebView的使用
  2. 【超越EfficientNet】无需注意力,Transformer结合视觉任务实现新SOTA
  3. python交互界面的退出
  4. 勒索软件可能已被“终极”解决
  5. SVN mime-type 笔记
  6. 浅谈SpringBoot的基本概念与简单的使用与yml文件的基本使用, 整合Redis,整合MyBatis
  7. poj1743(后缀数组+二分--不可重叠最长重复子串)
  8. [电子商务网站设计] 之 My Space
  9. 微软开始提供公共预览版Windows 8.1下载
  10. 【错误记录】python requests库 Response 判断坑
  11. hive-05-Execution Error, return code 3 from org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask
  12. html搜题软件,大学搜题app哪个好_大学好的搜题软件_大学搜题免费
  13. 扩展BSGS-传送门
  14. Android P功能
  15. 简单的print函数的实现
  16. 【学习笔记】统计学入门(5/7)——二项分布
  17. python 等值面_ANSYS Fluent快速添加等值面/等值线 源代码-教育代码类资源
  18. tlwr842n服务器无响应,TL-WR842n无线路由器掉线解决方法汇总
  19. 怎样才能让自己的QQ号永远不会被盗?
  20. 2016书单总结--看透SpringMvc源代码分析与实践-概述

热门文章

  1. 如何使用Java将字符串保存到文本文件?
  2. javascript页面刷新与定时跳转页面
  3. 每个叶子节点(nil)是黑色。_填充每个节点的下一个右侧节点指针
  4. python竞赛试题及答案_【技术分享】用python解NOIP竞赛题
  5. jframe大小根据组件变化_Swing JDialog容器和JFrame容器使用教程
  6. 百度网页搜索无法通过域名访问_网站换域名或网页内容改版对网站的影响以及网站换域名注意事项...
  7. 履带式机器人运动模型及应用分析(图片版)
  8. 英语听说计算机考试演练专用,新中高考英语听说机考时间确定,月底中考模考演练...
  9. java开发微信提现_java 微信提现至零钱
  10. oracle数据库赋权_Oracle角色权限创建用户赋权