一、volatile
java虚拟机提供的轻量级同步机制:
1.保证可见性 :一个线程修改有volatile修饰的变量,其他线程都能感知最后修改的值
2.不保证原子性
3.禁止命令重排序
解决原子性:添加syns或者使用AtomicInteger
原子性:(不可分割,完整性,某个线程正在做某个具体业务时,中间不可以被加塞或者被分割,需要整体完整,要么同时成功,要么同时失败)
JMM(java内存模型)
![](https://i-blog.csdnimg.cn/blog_migrate/31f234f37f1c49f8b2c4c808351cbf29.png)
![](https://i-blog.csdnimg.cn/blog_migrate/537026d68e4e019388d721cc8f5d2717.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0263db80495b40e1e454370a06c191d3.png)
总结:所有变量在主内存,所有线程都可以访问,线程操作变量需要把主内存的变量拷贝到工作内存操作,操作完成后写回主内存,并且通知其它线程我已经修改了。
![](https://i-blog.csdnimg.cn/blog_migrate/29045f7631a984537b09df0a49250a66.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9c5222a2f3bd5c75bbd2b772f01eca56.png)
指令重排:
![](https://i-blog.csdnimg.cn/blog_migrate/e14f5e375f492ad190ac90b25ff3df21.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bc8e883b1b882b025b8edcc598804275.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a9a9623fed8a5c4810747c75e964abf1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/241d91cc1c240d07f34f916322510733.png)
应用场景:
1.单例模式 DCL代码
2.单例模式volatile
![](https://i-blog.csdnimg.cn/blog_migrate/9a52dc6b763bd5d79137a90f9c4a914c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a35edc22932e4f44fd13e4c688b5221b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ffed4be51fa3df369f2d245db31e7f89.png)
JMM:
1.可见性
2.原子性
3.有序性
二、CAS
1.cas是什么?
AtomicInteger 底层:Unsafe类+CAS思想(自旋)
![](https://i-blog.csdnimg.cn/blog_migrate/925f364412153eb83b281e4213f97661.png)
比较并交换 compareAndSet
![](https://i-blog.csdnimg.cn/blog_migrate/9ea0da0669859254ce554b228473b480.png)
![](https://i-blog.csdnimg.cn/blog_migrate/88458b0d64b2e677ed4f5026710113dc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5afb59a7af7715d104ea030f5a85da79.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a3a1ef3ef26b8c47abe88d2a6cc45051.png)
![](https://i-blog.csdnimg.cn/blog_migrate/521ac13e5ed9a9fb50f1c8e9a0b9ace4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ddfc314ca99fa9ec3827609d02f1377d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6304ebe0f9737338dd7fef2b34caaae0.png)
总结:
![](https://i-blog.csdnimg.cn/blog_migrate/9f575c846391c16660b27df438841fac.png)
缺点:
1.循环时间长,cpu开销大。
![](https://i-blog.csdnimg.cn/blog_migrate/9af42c0c552dadb9f364c593291615d2.png)
2.只能保证一个共享变量得原子操作。
3.ABA问题.
![](https://i-blog.csdnimg.cn/blog_migrate/df105782ce78572e4b2915326851d13b.png)
解决aba方案:
1.原子引用,使用AtomicReference
2.时间戳原子引用或加版本号。AtomicStampeReference
三、集合类
1.ArrayList
(线程不安全)
new ArrayList(); 就是创建一个空的数组,初始化长度10,扩容是50%
![](https://i-blog.csdnimg.cn/blog_migrate/c2db626fccebb2f24895378b1db0d54d.png)
解决使用:Vector 或者Collections.synchronizedList(new ArrayList<>())或者 CopyOnWirteArrayList<>();
CopyOnWirteArrayList 底层是volatile 修饰的Object[]
add方法源码:
![](https://i-blog.csdnimg.cn/blog_migrate/8696c65527aaf0bd14bba935ab7d0c71.png)
2.SET/HashSet
(线程不安全)
![](https://i-blog.csdnimg.cn/blog_migrate/4b9fdc75ca2c303309126e99bde1568c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ca53e96f66fbfcb966a10150b11aa399.png)
也会报错:java.util.ConcurrentModificationException
解决使用:Collections.synchronizedSet(new HashSet<>())或者 CopyOnWirteArraySet<>();
CopyOnWirteArraySet底层:
![](https://i-blog.csdnimg.cn/blog_migrate/72881278242ffdf91cd4d3c002f9dae3.png)
HashSet底层就是HashMap ,只使用了key,value是一个常量。
![](https://i-blog.csdnimg.cn/blog_migrate/027f7d75e3bf2bc169f1a8a25a692c81.png)
![](https://i-blog.csdnimg.cn/blog_migrate/98878907da068f68d322381ec2f2916c.png)
3.Map/HashMap
(线程不安全)
![](https://i-blog.csdnimg.cn/blog_migrate/8aa0fc3f7cc98f3c66c4f7462ab82eae.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1cc6aef27ec27a95ce740175365cdf0e.png)
解决使用:ConcurrentHashMap或者Collections.synchronizedMap(new HashMap<>())
练习题:String str="abc"; 当前str="xxx";的时候相当于new String(); 所以在main方法中打印的还是abc的值
![](https://i-blog.csdnimg.cn/blog_migrate/74b9adf8b2a6e30e08a2e3a5eee634ad.png)
四、公平锁/非公平锁/可重入锁(
递归锁
)/独占锁/共享锁
/自旋锁
1.公平和非公平锁
Lock lock=new ReentrantLock();非公平锁 如果传值如下:
公平锁:多个线程按照申请锁的顺序来获取锁,类似排队打饭,先来后到。
非公平锁:多个线程获取锁的顺序不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发的情况下,有可能会造成优先级
![](https://i-blog.csdnimg.cn/blog_migrate/22c3bab1746da8f23227350e3bc12737.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f06e05169cb7d9091a6271e6c9830da4.png)
反转或者饥饿现象
![](https://i-blog.csdnimg.cn/blog_migrate/da1225c196fb85d289067de76c63432e.png)
2.可重入锁(递归锁)
![](https://i-blog.csdnimg.cn/blog_migrate/6794864add390679a82eef2886389c1f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/73695faa54486265dc8b9b20dfbe7d6f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/333a42612e23a37a6a00550bbf9ee3ab.png)
![](https://i-blog.csdnimg.cn/blog_migrate/450a532f4cf39e97ea6b9dc2563ec79e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9065533f7e237525619292c532bdb953.png)
3.自旋锁
![](https://i-blog.csdnimg.cn/blog_migrate/13f97b5eb8c31bae4a1541e8d946f6cb.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1e1ed394d5f4a9137075a6341f8edaa5.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ca4c2a002870caf9d8994ae68361ab76.png)
4.独占锁(写锁
)/共享锁(读锁)/互斥锁
![](https://i-blog.csdnimg.cn/blog_migrate/08932f7199fd29c69e7ea07fe3f05b53.png)
![](https://i-blog.csdnimg.cn/blog_migrate/155bdf0aca13d20168499cb533a2a18a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/aa036d6c48b919ef0476380999629842.png)
![](https://i-blog.csdnimg.cn/blog_migrate/393d1e338911d27dc7b2dbafe58f46bd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/200ead437fca8435cbff0acecab5747d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f239cb115970d70af9f467d987b3d92a.png)
偏向锁:
![](https://i-blog.csdnimg.cn/blog_migrate/7389d014100f9c0bf04c576898cd7bcd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4e22af050ce7d7d272a3228183b9c1c9.png)
轻量级锁:
![](https://i-blog.csdnimg.cn/blog_migrate/1d7418ea64868b0ed9fb3d5714f0e7d3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f7b11b9506838f228518e0dedb61bddb.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7bfdc776e35b57ee345b04939bb96d2e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bd1938f133103c422c815d5dd3e2f3c1.png)
2偏向锁
大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,偏向锁可以降低多次加锁解锁的开销。