CountDownLatch 实现公平测量cas、synchronized以及ReenTrantLock并发锁性能

1.cas

它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true。否则,返回 false。

2. synchronized的三种应用方式
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:
    普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
    静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
    同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁

3. ReenTrantLock 实现接口Lock

ReentrantLock是一个互斥锁,也是一个可重入锁(Reentrant就是再次进入的意思)。ReentrantLock锁在同一个时间点只能被一个线程锁持有,但是它可以被单个线程多次获取,每获取一次AQSstate就加1,每释放一次state就减1。还记得synchronized嘛,它也是可重入的,一个同步方法调用另外一个同步方法是没有问题的。

废话不多说,上代码:

  1 public static void main(String[] args)throws Exception {
  2         CountDownLatch countDownLatch = new CountDownLatch(1);//比较公平测量
  3         //全局变量时候使用:volatile这个关键子的作用是修饰类的全局变量的
  4         int k =0, m = 0,n=0,p=0;
  5         Lock lock = new ReentrantLock(false);
  6         Lock lockFair = new ReentrantLock(true);
  7         Long time =System.currentTimeMillis();
  8         //无锁
  9         Run run = new Run(k,time,countDownLatch);
 10         //sync锁
 11         RunSyn runSyn = new RunSyn(p,time,countDownLatch);
 12         //reentrantLock 非公平锁
 13         RunLock runLock = new RunLock(m,lock,time,"unfair",countDownLatch);
 14         //reentrantLock  公平锁
 15         RunLock runLockFair = new RunLock(m,lockFair,time,"fair",countDownLatch);
 16         //cas 锁
 17         RunCas runCas = new RunCas(n,new AtomicInteger(),time,countDownLatch);
 18         for (int i = 0; i < 3; i++) {
 19             new Thread(runLockFair).start();
 20             new Thread(run).start();
 21             new Thread(runLock).start();
 22             new Thread(runCas).start();
 23             new Thread(runSyn).start();
 24         }
 25         System.out.println("---------》比赛开始《--------");
 26         countDownLatch.countDown();//启动所有阻塞的线程
 27     }
 28 
 29     /**
 30      * 无 锁
 31      */
 32     static class Run implements Runnable{
 33         int k;
 34         Long time;
 35         CountDownLatch countDownLatch;
 36         public Run(int j,Long time,CountDownLatch countDownLatch){
 37             this.k = j;
 38             this.time = time;
 39             this.countDownLatch = countDownLatch;
 40         }
 41         @Override
 42         public void run() {
 43             try {
 44                 countDownLatch.await();
 45             } catch (InterruptedException e) {
 46                 e.printStackTrace();
 47             }
 48             for (int i = 0; i < 1000000; i++) {
 49                 k++;
 50                 //System.out.println("i--->"+i);
 51             }
 52             System.out.println("无锁 k--->"+k+"---->"+(System.currentTimeMillis()-time));
 53         }
 54     }
 55 
 56     /**
 57      * lock 锁
 58      */
 59      static class RunLock implements Runnable{
 60         int m;
 61         String sync;
 62         Long time;
 63         Lock lock;
 64         CountDownLatch countDownLatch;
 65         public RunLock(int j,Lock lock,Long time,String sync,CountDownLatch countDownLatch){
 66             this.m = j;
 67             this.time = time;
 68             this.lock = lock;
 69             this.sync = sync;
 70             this.countDownLatch = countDownLatch;
 71         }
 72         @Override
 73         public void run() {
 74             try {
 75                 countDownLatch.await();
 76             } catch (InterruptedException e) {
 77                 e.printStackTrace();
 78             }
 79             for (int i = 0; i < 1000000; i++) {
 80                 lock.lock();
 81                 m++;
 82                 lock.unlock();
 83             }
 84             System.out.println(sync+"lock m--->"+m+"---->"+(System.currentTimeMillis()-time));
 85         }
 86     }
 87 
 88     /**
 89      * CAS
 90      */
 91     static class RunCas implements Runnable{
 92         AtomicInteger atomicInteger;
 93         int n;
 94         Long time;
 95         CountDownLatch countDownLatch;
 96         public RunCas(int j,AtomicInteger atomicInteger,Long time,CountDownLatch countDownLatch){
 97             this.n = j;
 98             this.time = time;
 99             this.atomicInteger = atomicInteger;
100             this.countDownLatch = countDownLatch;
101         }
102         @Override
103         public void run() {
104             try {
105                 countDownLatch.await();
106             } catch (InterruptedException e) {
107                 e.printStackTrace();
108             }
109             for (int i = 0; i < 1000000; i++) {
110                 getLock(atomicInteger);
111                 n++;
112                 unLock(atomicInteger);
113             }
114             System.out.println("cas n--->"+n+"---->"+(System.currentTimeMillis()-time));
115         }
116     }
117 
118     /**
119      * 获取锁
120      * @param atomicInteger
121      * @return
122      */
123     private static boolean getLock(AtomicInteger atomicInteger) {
124         while (true){
125             boolean flag = atomicInteger.compareAndSet(0,1);
126             if (flag){
127                 return true;
128             }
129         }
130     }
131 
132     /**
133      * 释放锁
134      * @param atomicInteger
135      * @return
136      */
137     private static boolean unLock(AtomicInteger atomicInteger) {
138         while (true){
139             boolean flag = atomicInteger.compareAndSet(1,0);
140             if (flag){
141                 return true;
142             }
143         }
144     }
145 
146     /**
147      * synchronized
148      */
149     static class RunSyn implements Runnable{
150         int p;
151         Long time;
152         CountDownLatch countDownLatch;
153         public RunSyn(int j,Long time,CountDownLatch countDownLatch){
154             this.p = j;
155             this.time = time;
156             this.countDownLatch = countDownLatch;
157         }
158         @Override
159         public void run() {
160             try {
161                 countDownLatch.await();//阻塞线程
162             } catch (InterruptedException e) {
163                 e.printStackTrace();
164             }
165             synchronized(this){
166                 for (int i = 0; i < 1000000; i++) {
167                     p++;
168                 }
169             }
170             System.out.println("synchronized p--->"+p+"---->"+(System.currentTimeMillis()-time));
171         }
172     }

 

结果:

---------》比赛开始《--------
synchronized p--->1007776---->15
synchronized p--->2000000---->15
无锁 k--->246073---->31
无锁 k--->1108336---->46
无锁 k--->1247421---->46
synchronized p--->3000000---->46
unfairlock m--->2824215---->109
unfairlock m--->2959808---->109
unfairlock m--->3000000---->109
cas n--->2961861---->375
cas n--->2961864---->375
cas n--->3000000---->375
fairlock m--->2995778---->32035
fairlock m--->3000000---->32082
fairlock m--->3000000---->32082

 三个线程每个线程累加一百万,从结果看出来无锁出现并发问题,synchronized 性能最好  非公平锁unfairlock与cas性能差不多 公平锁fairlock性能较差

 

上一篇:同步工具类 CountDownLatch 和 CyclicBarrier


下一篇:枚举加countdownLatch的使用