JAVA锁 总结

    xiaoxiao2022-07-04  110

    一.自旋锁

        定义:是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

        优点:自旋锁不会使线程状态发生切换,一直处于用户态,即线程一直都是active的;不会使线程进入阻塞状态,减少了不必要的上下文切换,执行速度快。

        缺点:如果某个线程持有锁的时间过长,就会导致其它等待获取锁的线程进入循环等待,消耗CPU。使用不当会造成CPU使用率极高。

     

    二.阻塞锁

        定义:让线程进入阻塞状态进行等待,当获得相应的信号(唤醒,时间) 时,才可以进入线程的准备就绪状态,准备就绪状态的所有线程,通过竞争,进入运行状态;Java中的阻塞锁包括( synchronized 关键字(其中的重量锁),ReentrantLock,Object.wait()\notify() )。

        优点:阻塞的线程不会占用cpu时间, 不会导致 CPU占用率过高。

        缺点:存在上下文切换时间的消耗,执行速度比自旋锁要慢。

     

    三.可重入锁

        定义:可重复可递归调用的锁;ReentrantLock和Synchronized是可重入锁。

        优点:避免了频繁的持有释放操作,提升了效率的同时又避免了死锁。

     

    四.读写锁

        定义:表示两个锁,一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为排他锁。(适用场景:写操作没有读操作频繁);(三大特性:1.公平选择性,2.重入性,3.锁降级)

        读锁:进入前提是1.没有其他线程的写锁;2.没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。

        写锁:进入前提是1.没有其他线程的读锁;2.没有其他线程的写锁。

     

    五.互斥锁

        定义:通过竞争对资源的独占使用。

        与同步锁的区别:互斥的线程没有固定的执行顺序;而同步的线程是按照一定的逻辑顺序占有资源,协同完成任务。

     

    六.悲观锁

        定义:总是假设最坏的情况,对数据进行上锁;其他线程需要访问时都会阻塞挂起。(Synchronized的思想就是悲观锁)。

        

    七.乐观锁

        定义:总是假设最好的情况,不对数据进行上锁;但是会在更新是判断数据有没有变动,一般使用版本号机制或者CAS来实现乐观锁。

        版本号机制:给数据表加上version字段,每次更新是对version+1;更新前用已知版本号与数据库版本号进行比较,相等则更新,不等则说明数据被改动,重试更新,直至更新完成为止。

        CAS方式:CAS即compare and swap 或者 compare and set;进行操作时需要传 期望值(expected_value)和更新值(new_value),然后用expected与内存值(current_value)进行比较,如果相等则进行更新,不等则进行自旋操作。

     

    八.公平锁

        定义:尝试加锁时先判断是否有线程排队在等待,有的话优先处理排在队列的线程。

     

    九.非公平锁

        定义:线程加锁直接尝试获取锁,是以抢占的方式获取,是随机的。

        与公平锁的比较:公平锁牺牲了性能来保证了线程访问数据的公平性;非公平锁则放弃公平性来提高性能。

    待续...

     

    最新回复(0)