标签:util 恢复 无锁编程 进入 次数 idt mamicode 虚拟机 乐观锁和悲观锁
1.乐观锁和悲观锁
对于同一个共享资源,悲观锁认为,在自己使用数据的时间内,一定会有其它的线程来使用该数据,所以必须要对这个共享资源进行上锁,如果不上锁,在这期间数据可能会被其它的线程锁修改。java中的synchronized和Lock的实现类都是悲观锁。
而对于乐观锁而言,认为自己在使用共享资源期间,其它的线程不会修改共享资源,所以不会上锁,只是在更新这个共享资源的时候,去判断有没有其它的线程更新了这个数据,如果没有更新,则直接更新,如果更新了,则采取相应的处理方法。乐观锁在java中是通过使用无锁编程来实现的,最常用的是CAS算法。java中的原子类就是通过CAS自旋来实现的。
由以上可知悲观锁适合写多的操作,因为这样可以保证共享资源的准确性。乐观锁适合多读的操作,这样多个线程对数据的读操作,就不用等待获取锁。
乐观锁和悲观锁在使用方式也有差别,悲观锁往往需要在获取锁和释放锁之间进行同步操作,而乐观锁直接进行操作就好了。
乐观锁是如何实现不锁住对象,也能保证线程的同步呢。
CAS全称 Compare And Swap(比较与交换),是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。
最常见的就是Java.util.current类中的原子类,通过自旋的方式来实现变量同步。
2。自旋锁和适应性自旋锁
在唤醒线程或阻塞线程需要CPU切换状态,如果cpu切换状态的时间比代码执行的时间还长,那明显是不合适的。
在许多场景中,同步资源的锁定时间很短,为了这一小段时间去切换线程,线程挂起和恢复现场的花费可能会让系统得不偿失。如果物理机器有多个处理器,能够让两个或以上的线程同时并行执行,我们就可以让后面那个请求锁的线程不放弃CPU的执行时间,看看持有锁的线程是否很快就会释放锁。而为了让线程等待一下,我们就需要让当前的线程进行自旋,如果在自旋完成后前面锁定同步资源的线程已经释放了锁,那么当前线程就可以不必阻塞而是直接获取同步资源,从而避免切换线程的开销。这就是自旋锁。
自旋锁缺点就是不能代替堵塞,虽然自旋锁节省了cpu切换线程的开销,但是占用了cpu的时间,如果锁被占用的时间很短,那么自旋的效果就会很好,但是如果锁被占用的时间很长,那么只会白白的浪费处理器的时间,
自适应意味着自旋的时间(次数)不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也是很有可能再次成功,进而它将允许自旋等待持续相对更长的时间。如果对于某个锁,自旋很少成功获得过,那在以后尝试获取这个锁时将可能省略掉自旋过程,直接阻塞线程,避免浪费处理器资源。
4.公平锁和非公平锁
公平锁是指,在多个线程安装申请获得锁的顺序来获取锁,只有最先申请锁的线程才能获取锁,其它申请同一个锁的线程全部进入阻塞状态,并按照申请锁的顺序进行排队获取锁。
非公平锁则不存在排队的问题,多个线程获取同一个锁,只要获取了锁,该线程就能运行,不管这个线程是否是第一个申请锁的线程,其它的线程全部进入阻塞状态。
公平锁与非公平锁内部的实现机制就是差一个同步队列,公平锁在每次获取锁的时候,都会判断当前线程是否是同步队列的第一个线程。
重入锁和非重入锁
重入锁表示的是如果一个线程获取了某个对象或者class的锁,那么该对象的多个同步方法都是可以进行调用的,如果是非重入锁,那么在线程获取锁后只能调用对象或class的一个同步方法或代码块,因为在调用对象的第2个同步区域时,上一个同步区域为执行完毕锁还未释放。
ReentrantLock和synchronized都是重入锁,重入锁和非重入锁最常见的类就是ReentrantLock和NonReentrantLock,在类的内部其实维持了一个status变量,默认为0,如果有被获取锁一次就+1,释放就减1,对于重入锁,如果status的值为0,则直接获取锁,如果不是0,则判断当前申请锁的线程是否是之前获取锁的线程,在释放锁的时候通过依次-1来将status归0,而对于非重入锁,如果status不等于0则直接进入阻塞状态,释放锁的时候之间将status归为0.
独享锁和共享锁
独享锁(排他锁)是指这个锁一次只能被一个线程所持有,如果线程A对数据加上了独享锁后,其它的线程不能在数据上再加锁了,获取排他锁后即能读又能写数据。synchronized和juc中的Lock实现类就是独享锁。
共享锁是指该锁可被多个线程所持有。如果线程T对数据A加上共享锁后,则其他线程只能对A再加共享锁,不能加排它锁。获得共享锁的线程只能读数据,不能修改数据。
reentrantreadwritelock包括了独享锁和共享锁,内部包括readlock (共享锁),writelock(独享锁)。
标签:util 恢复 无锁编程 进入 次数 idt mamicode 虚拟机 乐观锁和悲观锁
原文地址:https://www.cnblogs.com/laoyu-love-life/p/14814962.html