CAS CAS(Compare and Swap),即比较并替换。CAS的思想很简单:三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。 JUC就是java.util.concurrent下面的类包,专门用于多线程的开发。
- 锁是一种竞争机制,一个方法加锁,一个方法没有加锁,那么普通方法就会先运行,因为它不要去竞争!
- 被synchornized修饰的同步方法,锁的对象是方法的调用者。谁先调用,谁先执行!
- 被synchronized修饰和static修饰的方法,锁的对象是类的class对象,唯一的! 根据锁的添加到Java中的时间,Java中的锁,可以分为"同步锁"和"JUC包中的锁"。
同步锁
即通过synchronized关键字来进行同步,实现对竞争资源的互斥访问的锁。Java 1.0版本中就已经支持同步锁了。
同步锁的原理是,对于每一个对象,有且仅有一个同步锁;不同的线程能共同访问该同步锁。但是,在同一个时间点,该同步锁能且只能被一个线程获取到。这样,获取到同步锁的线程就能进行CPU调度,从而在CPU上执行;而没有获取到同步锁的线程,必须进行等待,直到获取到同步锁之后才能继续运行。这就是,多线程通过同步锁进行同步的原理!
JUC包中的锁
相比同步锁,JUC包中的锁的功能更加强大,它为锁提供了一个框架,该框架允许更灵活地使用锁,只是它的用法更难罢了。
JUC包中的锁包括:Lock接口,ReadWriteLock接口,LockSupport阻塞原语,Condition条件, AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三个抽象类,ReentrantLock独占锁,ReentrantReadWriteLock读写锁。
AbstractQueuedSynchronizer就是被称之为AQS的类,它是一个非常有用的超类,可用来定义锁以及依赖于排队阻塞线程的其他同步器;
ReentrantLock,ReentrantReadWriteLock,CountDownLatch,CyclicBarrier和Semaphore等这些类都是基于AQS类实现的。
AbstractQueuedLongSynchronizer 类提供相同的功能但扩展了对同步状态的 64 位的支持。两者都扩展了类 AbstractOwnableSynchronizer(一个帮助记录当前保持独占同步的线程的简单类)。
各种锁的理解
Lock接口的所有实现类
// 可重入锁(普通锁)
ReentrantLock
// 读锁
ReentrantReadWriteLock.ReadLock
// 写锁
ReentrantReadWriteLock.WriteLock
Lock锁的用法
// 以可重入锁为例
Lock lock = new ReentrantLock();
// 加锁
lock.lock();
try{
// 业务代码
}catch(){
}finally{
// 解锁
lock.unlock();
}
ReentrantLock
// 无参构造方法(默认非公平锁)
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
- 公平锁,非公平锁 公平锁:非常公平,不能插队,必须先来后到
非公平锁:非常不公平,允许插队,可以改变顺序(ReentrantLock锁默认为非公平锁)
- 可重入锁 拿到了外面的锁后,就可以拿到里面的锁了(里面的锁是自动获得的)
3.Synchonized 锁
4.Lock 锁:
- lock锁必须配对,相当于lock和 unlock 必须数量相同;
- 在外面加的锁,也可以在里面解锁;在里面加的锁,在外面也可以解锁;
-
自旋锁spinlock
-
死锁