1.cas
它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true。否则,返回 false。
2. synchronized的三种应用方式
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:
普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁
3. ReenTrantLock 实现接口Lock
ReentrantLock
是一个互斥锁,也是一个可重入锁(Reentrant就是再次进入的意思)。ReentrantLock
锁在同一个时间点只能被一个线程锁持有,但是它可以被单个线程多次获取,每获取一次AQS
的state
就加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性能较差