总览图

如果文中内容有错误,欢迎指出,谢谢。

悲观锁、乐观锁

悲观锁、乐观锁使用场景是针对数据库操作来说的,是一种锁机制。

悲观锁(Pessimistic Lock):顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁(Optimistic Lock):顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,即对数据做版本控制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

公平锁、非公平锁

公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得。

非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待。

ReentrantLock锁内部提供了公平锁与分公平锁内部类之分,默认是非公平锁,如:

   public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}

互斥锁、读写锁

互斥锁:指的是一次最多只能有一个线程持有的锁。在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问。 而现在, Lock提供了比synchronized机制更广泛的锁定操作, Lock和synchronized机制的主要区别: 
synchronized机制提供了对与每个对象相关的隐式监视器锁的访问,并强制所有锁获取和释放均要出现在一个块结构中,当获取了多个锁时, 它们必须以相反的顺序释放。synchronized机制对锁的释放是隐式的,只要线程运行的代码超出了synchronized语句块范围,锁就会被释放。而Lock机制必须显式的调用Lock对象的unlock()方法才能释放锁,这为获取锁和释放锁不出现在同一个块结构中,以及以更自由的顺序释放锁提供了可能。

读写锁:ReadWriteLock接口及其实现类ReentrantReadWriteLock,默认情况下也是非公平锁。

ReentrantReadWriteLock中定义了2个内部类,ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock,分别用来代表读取锁和写入锁,ReentrantReadWriteLock对象提供了readLock()和writeLock()方法,用于获取读取锁和写入锁。

java.util.concurrent.locks.ReadWriteLock接口允许一次读取多个线程,但一次只能写入一个线程:

  • 读锁 - 如果没有线程锁定ReadWriteLock进行写入,则多线程可以访问读锁。

  • 写锁 - 如果没有线程正在读或写,那么一个线程可以访问写锁。

其中:

  • 读取锁允许多个reader线程同时持有,而写入锁最多只能有一个writer线程持有。
  • 读写锁的使用场合是:读取数据的频率远大于修改共享数据的频率。在上述场合下使用读写锁控制共享资源的访问,可以提高并发性能。
  • 如果一个线程已经持有了写入锁,则可以再持有读锁。相反,如果一个线程已经持有了读取锁,则在释放该读取锁之前,不能再持有写入锁。
  • 可以调用写入锁的newCondition()方法获取与该写入锁绑定的Condition对象,此时与普通的互斥锁并没有什么区别,但是调用读取锁的newCondition()方法将抛出异常。

参考

http://www.cnblogs.com/hane/p/7344572.html

http://www.cnblogs.com/jalja/p/5895051.html

http://www.cnblogs.com/aspirant/p/6747115.html

Java中的锁-悲观锁、乐观锁,公平锁、非公平锁,互斥锁、读写锁的更多相关文章

  1. Java中的常见锁(公平和非公平锁、可重入锁和不可重入锁、自旋锁、独占锁和共享锁)

    公平和非公平锁 公平锁:是指多个线程按照申请的顺序来获取值.在并发环境中,每一个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个就占有锁,否者就会加入到等待队列中,以 ...

  2. QThread中的互斥、读写锁、信号量、条件变量

    该文出自:http://www.civilnet.cn/bbs/browse.php?topicno=78431 在gemfield的<从pthread到QThread>一文中我们了解了线 ...

  3. 【Qt开发】QThread中的互斥、读写锁、信号量、条件变量

    在gemfield的<从pthread到QThread>一文中我们了解了线程的基本使用,但是有一大部分的内容当时说要放到这片文章里讨论,那就是线程的同步问题.关于这个问题,gemfield ...

  4. Java精通并发-自旋对于synchronized关键字的底层意义与价值分析以及互斥锁属性详解与Monitor对象特性解说【纯理论】

    自旋对于synchronized关键字的底层意义与价值分析: 对于synchronized关键字的底层意义和价值分析,下面用纯理论的方式来对它进行阐述,自旋这个概念就会应运而生,还是很重要的,下面阐述 ...

  5. Java中 equals和==的区分, new Integer和 非new的区别

    浅谈 equals 和 == ,new出的Integer和非new出的Integer 首先我们要知道在 == 比较的是内存地址值(不包括8种基本数据类型) equals比较的是两个值(内容)是否相同. ...

  6. java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)

    import java.util.concurrent.locks.*; class DuckMsg{ int size;//烤鸭的大小 String id;//烤鸭的厂家和标号 DuckMsg(){ ...

  7. Java中的四种权限修饰符及六种非访问修饰符(简识)

    一.是哪四种访问权限修饰符呢? public > protected > [default] > private (公共的 ) (受保护的) (默认的) (私有的) 二.简单认识四种 ...

  8. java中的悲观锁和乐观锁实现

    悲观锁就是认为并发时一定会有冲突发生,采用互斥的策略.比如java中的synchronized. 而乐观锁是假设并发时不会有冲突发生,如果发生冲突,则操作失败,并不断重试.乐观锁的机制就是CAS(Co ...

  9. 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

    网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...

  10. 写文章 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

    网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...

随机推荐

  1. docker使用 Flannel(etcd+flannel)网络

    一.Flannel网络简介 Flannel是一种基于overlay网络的跨主机容器网络解决方案,也就是将TCP数据包封装在另一种网络包里面进行路由转发和通信,Flannel是CoreOS开发,专门用于 ...

  2. windows安装解压版postgresql

    1.postgresql解压版下载 2.将下载的postgresql-12.1-1-windows-x64-binaries.zip解压 data文件夹后面初始化数据库时手动创建的 3.初始化数据库 ...

  3. 使用kombu的producer pool 向rabbitmq瞬间发送大量消息

    kombu比pika感觉考虑得全面多了,不知道为什么用的人好像少? 生产端是 python-socket.io 的client   接受socketio 消息后, 发到rabbitmq 按时序进行处理 ...

  4. JavaWeb_(Struts2框架)参数传递之接收参数与传递参数

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  5. Vue_(组件通讯)组件

    Vue组件 传送门 组件Component,可扩展HTML元素,封装可重用的代码.通俗的来说,组件将可重用的HTML元素封装成为标签方便复用: 组件的使用: 使用全局方法Vue.extend创建构造器 ...

  6. linux命令---vi编辑器快速定位行数

    linux命令—vi编辑器快速定位行数.删除当前行.和删除当前行后面的全部内容 1.vi 编辑器如何快速定位到第N行 命令方式下 :n http://bbs.chinaunix.net/thread- ...

  7. HAOI2010软件安装

    首先tarjan缩点应该能看出来,然后我用topsort跑了个DAG上的一维dp,结果WA的很惨. 其实用DAG应该也能做,但是DAG强调整体顺序,而对一些局部问题,例如两个儿子怎么分配,是否给当前节 ...

  8. java生成10个不相等的1-20的随机数

    public class Test { public static void main(String[] args){ Random ran = new Random(); Set <Integ ...

  9. Appium+Robotframework实现iOS应用的自动化测试

    Appium+Robotframework实现iOS应用的自动化测试 连接地址: 地址:https://blog.csdn.net/wd168/article/month/2016/06 1.http ...

  10. koa 基础(十四)cookie 的基本使用

    1.app.js /** * cookie的简介: * 1.cookie保存在浏览器客户端 * 2.可以让我们用同一个浏览器访问同一个域名的时候共享数据 * * cookie的作用: * 1.保存用户 ...