显示锁和AQS

显示锁和内置锁

        Synchronized属于内置锁。Lock接口属于显示锁。

Lock

        Lock类是一个接口,核心方法有lock(),unLock(),tryLock()

synchronized和lock比较  

        synchronized会比lock消耗的性能会少一点。因为lock是一个类,使用时需要创建一个对象的实例。而lock又比synchronized使用起来更灵活。

Lock的两个实现类

        Lock接口有两个实现用到的比较多:ReentrantLock(可重入锁,默认是非公平锁)和ReentrantReadWriteLock(读写锁)

Lock使用范式

    try{

        lock.Lock();

            //做业务逻辑

        } finally{

            //解锁

            lock.unlock();

        }

可重入锁

        不能锁自己,比如递归调用时,可以继续进入这把锁。

所谓锁的公平和非公平

        公平就是竞争锁的线程排队等候获取锁,等待时间最长的线程先拿锁,后来的排队等候。非公平就是谁先抢到就是谁的(因为线程从等待到唤醒需要上下文切换的时间,而这时正好有新的线程来拿锁,可能新来的线程先拿到)。Syn是非公平锁。

        公平锁和非公平锁其实不是由aqs来管的,是由实现这个锁来管的。非公平锁就是先尝试抢一次,如果抢到了则获取锁。公平锁是判断当前队列有没有节点等待,如果有的话则放到队列尾部等待。

读写锁

        创建读写锁:ReentrantReadWriteLock是实现类,ReadWriteLock是接口,如果要创建的话应该是ReadWriteLock lock = new ReentrantReadWriteLock();

        读写锁的机制:写独占,读共享,但是读写互斥。

        ReentrantReadWriteLock:ReentrantReadWriteLock实现上,读和写用的是一把锁,通过sync里的status值来记录的,因为status是int型,32位,高(16-32)16位用来记录读锁,低(0-16)16位用来记录写锁,而可重入的读锁通过ThreadLocal来实现记录重入次数。

Condition接口

        类似于syn中用到的notify和wait方法。配合Lock使用。Signal()方法对应notify,await()方法对应wait方法。唤醒基本用signal,而不用signalAll。

LockSupport

        LockSupport定义了一组的公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能,park方法是阻塞线程,unPark(Thread thread)是唤醒线程。而LockSupport 也成为构建同步组件的基础工具。

CLH

        队列锁。每一个锁都有两个参数,myPred和locked,locked等于当前线程使用锁的情况,myPred是一个自旋规则,会不断的向前面的线程查看locked值,当前面线程使用完锁后,会把自己的locked置为false,本线线程就能使用该锁了,当使用完再把自己的locked置为fasle,供后面的线程使用。

AQS(AbstractQueuedSynchronizer同步器)

        同步器的设计基于模板方法模式。,定义一个操作中的算法的骨架,而将一些步骤的实现延迟到子类中。模板方法模式最常见的使用就是spring框架中的各种template。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容