精华内容
下载资源
问答
  • 共享锁和独占锁 独占锁:独占锁也叫排他锁,是指该锁一次只能被一个线程所持有。如果线程对数据A加上排他锁后,则其他线程不能再对A加任何类型的锁。获得排它锁的线程即能读数据又能修改数据。 共享锁:共享锁是指该...

    共享锁和独占锁
    独占锁:独占锁也叫排他锁,是指该锁一次只能被一个线程所持有。如果线程对数据A加上排他锁后,则其他线程不能再对A加任何类型的锁。获得排它锁的线程即能读数据又能修改数据。
    共享锁:共享锁是指该锁可被多个线程所持有。如果线程对数据A加上共享锁后,则其他线程只能对A再加共享锁,不能加排它锁。获得共享锁的线程只能读数据,不能修改数据。

    展开全文
  • 共享锁和独占锁 独占锁:也是悲观锁 synchronized和ReentrantLock 共享锁接口: ReadWriteLock接口 共享锁:该锁可被多个线程共有,典型的就是ReentrantReadWriteLock里的读锁,它的读锁是可以被共享的,但是它的写...
        

    共享锁和独占锁

    独占锁:也是悲观锁
    synchronized和ReentrantLock

    共享锁接口:
    ReadWriteLock接口
    共享锁:该锁可被多个线程共有,典型的就是ReentrantReadWriteLock里的读锁,它的读锁是可以被共享的,但是它的写锁确每次只能被独占。

    reentrantreadwritelock example

    4165335-7f021003e3a423a2.png
    image.png

    展开全文
  • 59 对MySQL锁机制再深入一步,共享锁和独占锁到底是什么?l.pdf
  • 将这两个锁之前,我先讲下上一章遗留的...共享锁和独占锁 共享锁,顾名思义,就是这个锁是共享的,咱们能一起使用这个锁。这个就像进男厕所,以前的那种小便池,可以站很多人。 一般共享锁,使用是在读数据的基础上加

    将这两个锁之前,我先讲下上一章遗留的问题,就是ReentrantLock中的链表,就是下图中的这个内部静态类:

    其实这个类,一看就明白了,这个Node中包含了prev和next,这就是一个双向链表嘛。这个链表的作用就是用来存储线程的,给线程排队用的。并且由里面的waitStatus来实现锁的CAS操作。并由这个双向链表实现锁的自旋

    共享锁和独占锁

    共享锁,顾名思义,就是这个锁是共享的,咱们能一起使用这个锁。这个就像进男厕所,以前的那种小便池,可以站很多人。

    一般共享锁,使用是在读数据的基础上加锁。

    独占锁,意思就是,这个锁我占有了就只能我一个人使用,其他人都得等着。这个就像厕所里的坑位,一个坑位只能蹲一个人。前一个人完事儿了,后面的才能进去。

    一般独占锁,多用于写操作,也叫写锁。对数据的更新是不允许共享的。

    面试中,考官会这么问你:如果我一个事务里一个读操作和一个写操作,怎么保证我的数据是一致的?

    这两个锁玩意儿,一般用于数据库的比较多。不过这个独占锁(排它锁),我们实际情况也用的很多。

    其实这个题目,我当时想到了共享锁和排它锁,但是想了想都不对。就说了个加版本号,更新前比对下。其实,这个就是乐观锁的概念啦,只是当时不知道。

    上面我们讲到了自旋锁,那么自旋锁的出现是为了解决什么问题呢?

    锁自旋,就是当一个线程要去获取某个锁的时候,如果这个锁已被其他线程占用,那么这个线程就一直循环检测这个锁是否被释放,而不是挂起排队或进入睡眠等待。

    自旋锁适用于锁保护的临界区很小的情况,临界区很小的话,锁占用的时间就很短。

    乐观锁和悲观锁,咱们下章讲。。。

    展开全文
  • title: mysql共享锁和排它锁author: Joe Tongtags:JAVAEEMYSQLcategories:ITdate: 2020-05-29 15:35:53一、相关名词|--表级锁(锁定整个表)|--页级锁(锁定一页)|--行级锁(锁定一行)|--共享锁(S锁,MyISAM 叫做读锁)|-...

    title: mysql共享锁和排它锁

    author: Joe Tong

    tags:

    JAVAEE

    MYSQL

    categories:

    IT

    date: 2020-05-29 15:35:53

    一、相关名词

    |--表级锁(锁定整个表)

    |--页级锁(锁定一页)

    |--行级锁(锁定一行)

    |--共享锁(S锁,MyISAM 叫做读锁)

    |--排他锁(X锁,MyISAM 叫做写锁)

    |--悲观锁(抽象性,不真实存在这个锁)

    |--乐观锁(抽象性,不真实存在这个锁)

    二、InnoDB与MyISAM

    Mysql 在5.5之前默认使用 MyISAM 存储引擎,之后使用 InnoDB 。查看当前存储引擎:

    show variables like '%storage_engine%';

    MyISAM 操作数据都是使用的表锁,你更新一条记录就要锁整个表,导致性能较低,并发不高。当然同时它也不会存在死锁问题。

    而 InnoDB 与 MyISAM 的最大不同有两点:一是 InnoDB 支持事务;二是 InnoDB 采用了行级锁。也就是你需要修改哪行,就可以只锁定哪行。

    在 Mysql 中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql 语句操作了主键索引,Mysql 就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

    InnoDB 行锁是通过给索引项加锁实现的,如果没有索引,InnoDB 会通过隐藏的聚簇索引来对记录加锁。也就是说:如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。因为没有了索引,找到某一条记录就得扫描全表,要扫描全表,就得锁定表。

    三、共享锁与排他锁

    1.首先说明:数据库的增删改操作默认都会加排他锁,而查询不会加任何锁。

    |--共享锁:对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源(也可以再继续加共享锁,即 共享锁可多个共存),但无法修改。要想修改就必须等所有共享锁都释放完之后。语法为:

    select * from table lock in share mode

    |--排他锁:对某一资源加排他锁,自身可以进行增删改查,其他人无法进行任何操作。语法为:

    select * from table for update

    这里用T1代表一个数据库执行请求,T2代表另一个请求,也可以理解为T1为一个线程,T2 为另一个线程。

    例1:-------------------------------------------------------------------------------------------------------------------------------------

    T1:select * from table lock in share mode(假设查询会花很长时间,下面的例子也都这么假设)

    T2:update table set column1='hello'

    过程:

    T1运行(并加共享锁)

    T2运行

    If T1还没执行完

    T2等......

    else 锁被释放

    T2执行

    end if

    T2 之所以要等,是因为 T2 在执行 update 前,试图对 table 表加一个排他锁,而数据库规定同一资源上不能同时共存共享锁和排他锁。所以 T2 必须等 T1 执行完,释放了共享锁,才能加上排他锁,然后才能开始执行 update 语句。

    例2:-------------------------------------------------------------------------------------------------------------------------------------

    T1:select * from table lock in share mode

    T2:select * from table lock in share mode

    这里T2不用等待T1执行完,而是可以马上执行。

    分析:

    T1运行,则 table 被加锁,比如叫lockA,T2运行,再对 table 加一个共享锁,比如叫lockB,两个锁是可以同时存在于同一资源上的(比如同一个表上)。这被称为共享锁与共享锁兼容。这意味着共享锁不阻止其它人同时读资源,但阻止其它人修改资源。

    例3:-------------------------------------------------------------------------------------------------------------------------------------

    T1:select * from table lock in share mode

    T2:select * from table lock in share mode

    T3:update table set column1='hello'

    T2 不用等 T1 运行完就能运行,T3 却要等 T1 和 T2 都运行完才能运行。因为 T3 必须等 T1 和 T2 的共享锁全部释放才能进行加排他锁然后执行 update 操作。

    例4:(死锁的发生)-----------------------------------------------------------------------------------------------------------------

    T1:begin tran

    select * from table lock in share mode

    update table set column1='hello'

    T2:begin tran

    select * from table lock in share mode

    update table set column1='world'

    假设 T1 和 T2 同时达到 select,T1 对 table 加共享锁,T2 也对 table 加共享锁,当 T1 的 select 执行完,准备执行 update 时,根据锁机制,T1 的共享锁需要升级到排他锁才能执行接下来的 update。在升级排他锁前,必须等 table 上的其它共享锁(T2)释放,同理,T2 也在等 T1 的共享锁释放。于是死锁产生了。

    例5:-------------------------------------------------------------------------------------------------------------------------------------

    T1:begin tran

    update table set column1='hello' where id=10

    T2:begin tran

    update table set column1='world' where id=20

    这种语句虽然最为常见,很多人觉得它有机会产生死锁,但实际上要看情况

    |--如果id是主键(默认有主键索引),那么T1会一下子找到该条记录(id=10的记录),然后对该条记录加排他锁,T2,同样,一下子通过索引定位到记录,然后对id=20的记录加排他锁,这样T1和T2各更新各的,互不影响。T2也不需要等。

    |--如果id是普通的一列,没有索引。那么当T1对id=10这一行加排他锁后,T2为了找到id=20,需要对全表扫描。但因为T1已经为一条记录加了排他锁,导致T2的全表扫描进行不下去(其实是因为T1加了排他锁,数据库默认会为该表加意向锁,T2要扫描全表,就得等该意向锁释放,也就是T1执行完成),就导致T2等待。

    死锁怎么解决呢?一种办法是,如下:

    例6:-------------------------------------------------------------------------------------------------------------------------------------

    T1:begin tran

    select * from table for update

    update table set column1='hello'

    T2:begin tran

    select * from table for update

    update table set column1='world'

    这样,当 T1 的 select 执行时,直接对表加上了排他锁,T2 在执行 select 时,就需要等 T1 事物完全执行完才能执行。排除了死锁发生。但当第三个 user 过来想执行一个查询语句时,也因为排他锁的存在而不得不等待,第四个、第五个 user 也会因此而等待。在大并发情况下,让大家等待显得性能就太友好了。

    所以,有些数据库这里引入了更新锁(如Mssql,注意:Mysql不存在更新锁)。

    例7:-------------------------------------------------------------------------------------------------------------------------------------

    T1:begin tran

    select * from table [加更新锁操作]

    update table set column1='hello'

    T2:begin tran

    select * from table [加更新锁操作]

    update table set column1='world'

    更新锁其实就可以看成排他锁的一种变形,只是它也允许其他人读(并且还允许加共享锁)。但不允许其他操作,除非我释放了更新锁。T1 执行 select,加更新锁。T2 运行,准备加更新锁,但发现已经有一个更新锁在那儿了,只好等。当后来有 user3、user4...需要查询 table 表中的数据时,并不会因为 T1 的 select 在执行就被阻塞,照样能查询,相比起例6,这提高了效率。

    后面还有意向锁和计划锁:

    计划锁,和程序员关系不大,就没去了解。

    意向锁(innodb特有)分意向共享锁和意向排他锁。

    意向共享锁:表示事务获取行共享锁时,必须先得获取该表的意向共享锁;

    意向排他锁:表示事务获取行排他锁时,必须先得获取该表的意向排他锁;

    我们知道,如果要对整个表加锁,需保证该表内目前不存在任何锁。

    因此,如果需要对整个表加锁,那么就可以根据:检查意向锁是否被占用,来知道表内目前是否存在共享锁或排他锁了。而不需要再一行行地去检查每一行是否被加锁。

    四、乐观锁与悲观锁

    首先说明,乐观锁和悲观锁都是针对读(select)来说的。

    案例:

    某商品,用户购买后库存数应-1,而某两个或多个用户同时购买,此时三个执行程序均同时读得库存为“n”,之后进行了一些操作,最后将均执行update table set 库存数=n-1,那么,很显然这是错误的。

    解决:

    使用悲观锁(其实说白了也就是排他锁)

    |-- 程序A在查询库存数时使用排他锁(select * from table where id=10 for update)

    |-- 然后进行后续的操作,包括更新库存数,最后提交事务。

    |-- 程序B在查询库存数时,如果A还未释放排他锁,它将等待……

    |-- 程序C同B……

    使用乐观锁(靠表设计和代码来实现)

    |-- 一般是在该商品表添加version版本字段或者timestamp时间戳字段

    |-- 程序A查询后,执行更新变成了:

    update table set num=num-1 where id=10 and version=23

    这样,保证了修改的数据是和它查询出来的数据是一致的(其他执行程序肯定未进行修改)。当然,如果更新失败,表示在更新操作之前,有其他执行程序已经更新了该库存数,那么就可以尝试重试来保证更新成功。为了尽可能避免更新失败,可以合理调整重试次数(阿里巴巴开发手册规定重试次数不低于三次)。

    总结:对于以上,可以看得出来乐观锁和悲观锁的区别:

    悲观锁实际使用了排他锁来实现(select **** for update)。文章开头说到,innodb加行锁的前提是:必须是通过索引条件来检索数据,否则会切换为表锁。

    因此,悲观锁在未通过索引条件检索数据时,会锁定整张表。导致其他程序不允许“加锁的查询操作”,影响吞吐。故如果在查询居多的情况下,推荐使用乐观锁。

    “加锁的查询操作”:加过排他锁的数据行在其他事务中是不能修改的,也不能通过for update或lock in share mode的加锁方式查询,但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制。

    乐观锁更新有可能会失败,甚至是更新几次都失败,这是有风险的。所以如果写入居多,对吞吐要求不高,可使用悲观锁。

    也就是一句话:读用乐观锁,写用悲观锁。

    展开全文
  • java中有公平锁、非公平锁、可重入锁(递归锁)、自旋锁、独占锁(写锁)、共享锁(读锁)……编程公平锁 非公平锁并发是什么:公平锁:是指多个线程按照申请的顺序来获取值函数非公平锁:是值多个线程获取值的顺序并非...
  • java 并发包提供的加锁模式分为独占锁和共享锁独占锁 独占锁模式下,每次只能有一个线程能持有锁,ReentrantLock 就是以独占方式实现的互斥锁。 独占锁是一种悲观保守的加锁策略,它避免了读/读冲突,如果某个...
  • 其实是X锁,也就是Exclude独占锁,当有一个事务加了独占锁之后,此时其它事务再要更新这行数据,都是要加独占锁的,但是只能生成独占锁在后面等待。 当有人在更新数据的时候,其它的事务可以读取这行数据吗?默认...
  • 共享锁和独占锁的经典应用,是控制最初用于读取的共享文件的更新。某个进程要读取文件, 会先取得该文件或该文件部分区域的共享锁。第二个希望读取相同文件区域的进程也会请求共享 锁。两个进程可以并行读取,互不影响...
  • ... <p>I have to store last login time and ip user each time after user login. When user logins system stores it to <code>Redis</code> and I have script in crontab which executes each minute and ...
  • //独占锁的占用释放 AcquireSRWLockExclusive(&g_sCallNumberMapRwLock); ReleaseSRWLockExclusive(&g_sCallNumberMapRwLock); //共享锁的占用释放 AcquireSRWLockShared(&g_...
  • 【Java 多线程并发】Java (上)—— 乐观、悲观、自旋 【Java 多线程并发】Java (中)—— Synchronized 同步、ReentrantLock、Semaphonre 信号量、AtomicInteger 8. 可重入(递归) 本文...
  • 共享锁独占锁

    2012-04-29 17:27:34
    共享锁和独占锁的经典应用,是控制最初用于读取的共享文件的更新。某个进程要读取文件,会先取得该文件或该文件部分区域的共享锁。第二个希望读取相同文件区域的进程也会请求共享锁。两个进程可以并行读取,互不影响...
  • Lock锁底层依赖于AQS实现,AQS提供了多种锁的实现模式,其中独占锁和共享锁是...今天我们主要是比较AQS中共享锁和独占锁的底层实现方面的不同。public final void acquire(int arg){/*对外提供的独占锁的模板方法*/ ...
  • 对ReentrantLock和Synchronized而言都是独占锁共享锁:指该锁可以被多个线程锁持有对ReentrantReadWriteLock其读锁是共享,其写锁是独占写的时候只能一个人写,但是读的时候,可以多个人同时读为什么会有写锁和读锁...
  • 对ReentrantLockSynchronized而言都是独占锁共享锁:指该锁可被多个线程所持有。对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥...
  • 乐观锁和悲观锁:数据库的锁机制 在数据库管理系统中的并发控制是为了确保多个事务之间同时读取数据库中同一个数据是,不破坏事务的隔离性和统一性以及数据库的统一性。实现并发控制的手段大致可以分为乐观并发控制...
  • 同步锁和独占锁

    2016-07-29 22:21:05
    共享锁和独占锁的经典应用,是控制最初用于读取的共享文件的更新。 某个进程要读取文件,会先取得该文件或该文件部分区域的共享锁。第二个希望读取相同文件区域的进程也会请求共享锁。两个进程可以并行读取,互不...
  • AQS共享锁独占锁对比

    千次阅读 2020-03-05 23:23:28
    AQS框架图 上图是AQS框架大致的一些方法,还有一些没有全部的列出来。这里主要是让大家从这张图...共享模式和独占模式流程图对比 独占模式流程图 共享模式流程图 相同点 从流程图中,我们发现独占模式和共...
  • 共享锁独占锁简单介绍 共享锁:Shared Locks,简称S锁,可以多个事务共同持有,获得共享锁的事务只能读数据,不能修改数据。 假如事务1⾸先获取了⼀条记录的S锁,如果事务2想要获取这条记录的S锁,那么事务T2也能...
  • 文章目录1、公平锁和非公平锁2、可重入锁(递归锁)3、自旋锁3.1 手写一个自旋锁4、独占锁共享锁、互斥锁 1、公平锁和非公平锁 公平锁是指 多个线程按照申请锁的顺序来获取锁,根据先来后到的规则进行排队等候 。 ...
  • 一、公平与非公平1.1 概述公平:是指多个线程按照申请的顺序来获取。非公平:是指在多线程获取的顺序并不是按照申请的顺序,有可能后申请的线程比先申请的线程优先获取到,在高并发的情况下,有...
  • AQS全称AbstractQueueSynchronizer,在java.util.concurrent.locks包下,是构建锁和其他同步器的框架,它的定位是能够成为实现大部分同步需求的基础。Java中基于AQS的有ReentrantLock、Semaphore、读写锁、...
  • Java并发编程锁之独占公平锁与非公平锁比较公平锁和非公平锁理解:在上一篇文章中,我们知道了非公平锁。其实Java中还存在着公平锁呢。公平二字怎么理解呢?和我们现实理解是一样的。大家取排队本着先来先得到的原则...
  • 独占锁和共享锁

    2019-08-19 11:14:59
    多线程访问共享变量存在数据同时修改导致不一致问题,就需要来对共享数据的访问进行管理。 多个线程A B C 去竞争同一个L,存在线程获取的同步状态管理,排队获取,竞争获取,等待获取,释放唤醒其他...
  • java并发包提供的加锁模式分为独占锁和共享锁独占锁模式下,每次只能有一个线程能持有锁,ReentrantLock就是以独占方式实现的互斥锁。共享锁,则允许多个线程同时获取锁,并发访问 共享资源,如:ReadWriteLock。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,699
精华内容 679
关键字:

共享锁和独占锁