课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
锁的应用相信大家应该都不陌生的吧,尤其是我们在学习java编程开发语言的时候,更是需要熟练掌握锁的应用,下面我们就一起来了解一下,java编程常见锁的类型分享。
1、乐观锁
乐观锁是一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低,读数据时认为别的线程不会正在进行修改(所以没有上锁)。写数据时,判断当前与期望值是否相同,如果相同则进行更新(更新期间加锁,保证是原子性的)。
Java中的乐观锁:CAS,比较并替换,比较当前值(主内存中的值),与预期值(当前线程中的值,主内存中值的一份拷贝)是否一样,一样则更新,否则继续进行CAS操作。
2、悲观锁
悲观锁是一种悲观思想,即认为写多读少,遇到并发写的可能性高,每次去拿数据的时候都认为其他线程会修改,所以每次读写数据都会认为其他线程会修改,所以每次读写数据时都会上锁。其他线程想要读写这个数据时,会被这个线程block,直到这个线程释放锁然后其他线程获取到锁。
3、自旋锁
自旋锁是一种技术:为了让线程等待,我们只须让线程执行一个忙循环(自旋)。
现在绝大多数的个人电脑和服务器都是多路(核)处理器系统,如果物理机器有一个以上的处理器或者处理器核心,能让两个或以上的线程同时并行执行,就可以让后面请求锁的那个线程“稍等一会”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。
自旋锁的优点:避免了线程切换的开销。挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给Java虚拟机的并发性能带来了很大的压力。
自旋锁的缺点:占用处理器的时间,如果占用的时间很长,会白白消耗处理器资源,而不会做任何有价值的工作,带来性能的浪费。因此自旋等待的时间必须有一定的限度,如果自旋超过了限定的次数仍然没有成功获得锁,就应当使用传统的方式去挂起线程。
自旋次数默认值:10次,可以使用参数-XX:PreBlockSpin来自行更改。
自适应自旋:自适应意味着自旋的时间不再是固定的,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定的。有了自适应自旋,随着程序运行时间的增长及性能监控信息的不断完善,虚拟机对程序锁的状态预测就会越来越精准。
Java中的自旋锁:CAS操作中的比较操作失败后的自旋等待。
4、可重入锁(递归锁)
可重入锁是一种技术:任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞。
可重入锁的原理:通过组合自定义同步器来实现锁的获取与释放。
再次获取锁:识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取。获取锁后,进行计数自增,
释放锁:释放锁时,进行计数自减。
Java中的可重入锁:ReentrantLock、synchronized修饰的方法或代码段。
可重入锁的作用:避免死锁。
5、读写锁
读写锁是一种技术:通过ReentrantReadWriteLock类来实现。为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。读写锁分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的。
读锁:允许多个线程获取读锁,同时访问同一个资源。
写锁:只允许一个线程获取写锁,不允许同时访问同一个资源。
Java中的读写锁:ReentrantReadWriteLock
6、公平锁
公平锁是一种思想:多个线程按照申请锁的顺序来获取锁。在并发环境中,每个线程会先查看此锁维护的等待队列,如果当前等待队列为空,则占有锁,如果等待队列不为空,则加入到等待队列的末尾,按照FIFO的原则从队列中拿到线程,然后占有锁。
7、非公平锁
非公平锁
非公平锁是一种思想:线程尝试获取锁,如果获取不到,则再采用公平锁的方式。多个线程获取锁的顺序,不是按照先到先得的顺序,有可能后申请锁的线程比先申请的线程优先获取锁。
优点:非公平锁的性能高于公平锁。
缺点:有可能造成线程饥饿(某个线程很长一段时间获取不到锁)
Java中的非公平锁:synchronized是非公平锁,ReentrantLock通过构造函数指定该锁是公平的还是非公平的,默认是非公平的。
8、共享锁
共享锁是一种思想:可以有多个线程获取读锁,以共享的方式持有锁。和乐观锁、读写锁同义。
Java中用到的共享锁:ReentrantReadWriteLock。
9、独占锁
独占锁是一种思想:只能有一个线程获取锁,以独占的方式持有锁。和悲观锁、互斥锁同义。
Java中用到的独占锁:synchronized,ReentrantLock
10、重量级锁
重量级锁是一种称谓:synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本身依赖底层的操作系统的MutexLock来实现。操作系统实现线程的切换需要从用户态切换到核心态,成本非常高。这种依赖于操作系统MutexLock来实现的锁称为重量级锁。为了优化synchonized,引入了轻量级锁,偏向锁。
Java中的重量级锁:synchronized
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。