并发编程之同步
一、synchronized关键字:锁对象或类对象。加锁方法具备原子性。
1.synchronized方法和synchronized(this){}块:都是锁当前对象。
2.static synchronized:锁的是当前类的class对象。
3.加锁的目的:保证操作的原子性。
4.同步和非同步方法调用。
5.可重入:同一个线程,多次调用同步代码,锁定同一个对象,可重入。
可重入最大的作用是避免死锁。
6.继承。都加锁后,可重入。
7.异常。当同步方法中发生异常,自动释放锁,不会影响其他线程的执行。
try catch
8.锁对象变更。锁的是对象,不是引用。
在锁未释放之前,修改锁对象引用,不会影响同步代码的执行。
9.常量问题。
在定义同步代码块时,不要使用常量对象作为锁对象。
10.Synchronized的三种用法:
- 当synchronized作用在实例方法时,监视器锁(monitor)便是对象实例(this);
- 当synchronized作用在静态方法时,监视器锁(monitor)便是对象的Class实例,因为Class数据存在于永久代,因此静态方法锁相当于该类的一个全局锁;
- 当synchronized作用在某一个对象实例时,监视器锁(monitor)便是括号括起来的对象实例;
二、volatile关键字:有可见性和有序性不保证原子性。
1.可见性和有序性
2.非原子性
三、AtomicXxx:原子性。效率高
1.AtomicInteger等
四、CountDownLatch:门闩。并发包:JUC中的类。
1.await():等待门闩开发
2.getCount():获取数量
3.CountDowm():减门闩上的锁。
CountDownLatch(5)
可以和锁一起使用,提高并发效率。
五、同步原理
1.数据同步需要依赖锁,那锁的同步又依赖谁?
synchronized:在软件层面依赖JVM。
j.u.c.Lock:在硬件层面依赖特殊的CPU指令。
2.监视器锁(monitor):每个对象都是一个监视器锁(monitor)。
Synchronized的语义底层是通过一个monitor的对象来完成。
1)monitorenter
2)monitorexit