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性能较差