共享锁

java 锁机制

喜欢而已 提交于 2020-01-30 21:21:12
公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁(实现秒杀的一种解决方案) (select * from product p where p.type=’xxxxx’ for update) 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁 这些分类并不是全是指锁的状态,有的指锁的特性,有的指锁的设计, 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁。 非公平锁是指多个线程获取锁的顺序并不按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。 对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。 对于Synchronized而言,也是一种非公平锁。由于其并不像ReentrantLock是通过AQS的来实现线程调度,所以并没有任何办法使其变成公平锁。 AQS 的核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。 CLH (Craig,Landin,and Hagersten)队列是一个虚拟的双向队列

java中常用的锁机制

*爱你&永不变心* 提交于 2020-01-28 20:44:38
基础知识 基础知识之一:锁的类型 锁就那么几个,只是根据特性,分为不同的类型 锁的概念 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制。锁旨在强制实施互斥排他、并发控制策略。 锁通常需要硬件支持才能有效实施。这种支持通常采取一个或多个原子指令的形式,如"test-and-set", "fetch-and-add" or "compare-and-swap"”。这些指令允许单个进程测试锁是否空闲,如果空闲,则通过单个原子操作获取锁。 锁的三个概念 1、锁开销 lock overhead 锁占用内存空间、 cpu初始化和销毁锁、获取和释放锁的时间。程序使用的锁越多,相应的锁开销越大 2、锁竞争 lock contention 一个进程或线程试图获取另一个进程或线程持有的锁,就会发生锁竞争。锁粒度越小,发生锁竞争的可能性就越小 3、死锁 deadlock 至少两个任务中的每一个都等待另一个任务持有的锁的情况锁粒度是衡量锁保护的数据量大小,通常选择粗粒度的锁(锁的数量少,每个锁保护大量的数据),在当单进程访问受保护的数据时锁开销小,但是当多个进程同时访问时性能很差。因为增大了锁的竞争。相反,使用细粒度的锁(锁数量多,每个锁保护少量的数据)增加了锁的开销但是减少了锁竞争。例如数据库中,锁的粒度有表锁、页锁、行锁、字段锁

数据库的事务与锁初理解

孤者浪人 提交于 2020-01-25 21:41:02
前沿: 以下内容大多来自以下三篇文章 Mysql事务与锁详解 MySqL 事务与锁的深入学习笔记 Mysql事务实现原理 (很推荐看下) 对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X); 对于一般的select语句,InnoDB不会加任何锁 ,事务可以通过以下语句给显式的加共享锁或排他锁。 -- 共享锁: SELECT * from tb_user LOCK IN SHARE MODE ; -- 排他锁: SELECT * from tb_user FOR UPDATE ; 共享锁(S) 排它锁(X) 若某个事物对某一行加上了排他锁,只能这个事务对其进行读写,在此事务结束之前,其他事务不能对其进行 加任何锁 (如何执行的语句没有锁,那么就不会影响, 比如默认的select语句就是没有任何锁的 ),其他进程可以读取,不能进行写操作,需等待其释放。 排它锁是悲观锁的一种实现 执行存储过程,开启事务,但是不提交,即锁一直在 CREATE DEFINER = ` root ` @`localhost` PROCEDURE ` NewProc ` ( ) BEGIN start transaction ; set session transaction isolation level read committed ; SELECT name

二、innodb的加锁

谁说我不能喝 提交于 2020-01-24 22:26:03
所有文章 https://www.cnblogs.com/lay2017/p/12078232.html 正文 在上一篇文章中,我们简单了解了一下innodb的 行级锁(s锁、x锁) 和 表级锁(is锁、ix锁) 的概念以及锁之间的兼容关系。 本文,将了解一下innodb的几种加锁的情况: 常见的加锁 1)对于 update、delete、insert 这种涉及到commit操作的语句,innodb自动会给相关的数据集加上 排它锁 (X锁)。 2)对于 普通的select语句 ,innodb 默认是不会加锁 的。但是,一个 事务中 我们可以 显示地 给select语句 加上共享锁(S锁)或者排它锁(X锁) 。这里注意,必须开启事务,在begin和commit/rollback之间才生效。   2-1)共享锁(S锁),例如:   select * from t_table where...lock in share mode   其它事务仍然可以查询记录,或者也加上share mode地共享锁,但不可以加互斥锁。同时要注意,如果当前事务加了共享锁,又准备对该数据进行更新操作(加排它锁),那么 可能就造成了死锁 。   2-2)排它锁(X锁),例如: select * from t_table where...for update   其它事务可以查询该记录

java - 锁的种类及详解

醉酒当歌 提交于 2020-01-24 16:43:49
锁类型 锁根据其特性能够划分出各种各样的锁类型,该文主要介绍以下锁的作用及特性 乐观锁/悲观锁 独享锁/共享锁 互斥锁/读写锁 可重入锁 公平锁/非公平锁 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁 乐观锁/悲观锁 乐观锁与悲观锁并不是特指某两种类型的锁,是人们定义出来的概念或思想,主要是指看待并发同步的角度。 乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(Compare and Swap 比较并交换,属于计算机底层的CPU原子操作)实现的。 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。比如Java里面的同步原语synchronized关键字的实现就是悲观锁。 悲观锁适合写操作非常多的场景,乐观锁适合读操作非常多的场景,不加锁会带来大量的性能提升。 乐观锁在Java中的使用,是无锁编程,常常采用的是CAS算法,典型的例子就是java.util.concurrent.atomic包下的原子类

Java多线程(9)

浪子不回头ぞ 提交于 2020-01-22 19:33:11
Java多线程(9) AQS(2) 锁的占有与释放 对于AQS来说,线程同步的关键是对状态值state进行操作,根据state是否属于一个线程,操作state的方式分为独占方式和共享方式 独占方式下获取和释放资源使用的方法为: public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); } public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }

转 事务隔离级别

可紊 提交于 2020-01-22 09:03:52
http://msdn.microsoft.com/zh-cn/library/ms173763.aspx SET TRANSACTION ISOLATION LEVEL (Transact-SQL) 更新日期: 2006 年 4 月 14 日 控制到 SQL Server 的连接发出的 Transact-SQL 语句的锁定行为和行版本控制行为。 Transact-SQL 语法约定 语法 SET TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SNAPSHOT | SERIALIZABLE } [ ; ] 参数 READ UNCOMMITTED 指定语句可以读取已由其他事务修改但尚未提交的行。 在 READ UNCOMMITTED 级别运行的事务,不会发出共享锁来防止其他事务修改当前事务读取的数据。 READ UNCOMMITTED 事务也不会被排他锁阻塞,排他锁会禁止当前事务读取其他事务已修改但尚未提交的行。 设置此选项之后,可以读取未提交的修改,这种读取称为脏读。 在事务结束之前,可以更改数据中的值,行也可以出现在数据集中或从数据集中消失。 该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 NOLOCK 相同。这是隔离级别中限制最少的级别。 在

死锁产生的原因和解锁的方法

China☆狼群 提交于 2020-01-18 04:00:55
一.产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 二 锁的分类 锁的类别有两种分法: 1. 从数据库系统的角度来看:分为独占锁(即排它锁),共享锁和更新锁 MS-SQL Server 使用以下资源锁模式。 锁模式描述:   共享 (S) :读锁,用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。   更新 (U) :( 介于共享和排它锁之间 ),可以让其他程序在不加锁的条件下读,但本程序可以随时更改。   读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束。UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。当我们用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改,我如下示例: BEGIN TRANSACTION --开始一个事务 SELECT Qty FROM myTable WITH (UPDLOCK) WHERE Id in (1,2,3) UPDATE

常见的表死锁情况及解决方法

可紊 提交于 2020-01-18 03:58:03
1、死锁的第一种情况 一个用户A 访问表A(锁住了表A),然后又访问表B;另一个用户B 访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。 解决方法 这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。 2、死锁的第二种情况 用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种死锁比较隐蔽,但在稍大点的项目中经常发生。如在某项目中,页面上的按钮点击后,没有使按钮立刻失效,使得用户会多次快速点击同一按钮,这样同一段代码对数据库同一条记录进行多次操作,很容易就出现这种死锁的情况。 解决方法 1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录操作。 2、使用乐观锁进行控制。乐观锁大多是基于数据版本

sqlserver事务隔离小结

我是研究僧i 提交于 2020-01-16 08:37:25
SQL Server通过在锁资源上使用不同类型的锁来隔离事务。为了开发安全的事务,定义事务内容以及应在何种情况下回滚至关重要,定义如何以及在多长时间内在事务中保持锁定也同等重要。这由隔离级别决定。应用不同的隔离级别,SQL Server赋予开发者一种能力,让他们为每一个单独事务定义与其他事务的隔离程度。事务隔离级别的定义如下: · 是否在读数据的时候使用锁 · 读锁持续多长时间 · 在读数据的时候使用何种类型的锁 · 读操作希望读已经被其他事务排他锁住的数据时,怎么办?在这种情况下, SQL Server 可以: · 一直等到其他事务释放锁 · 读没有提交的数据 · 读数据最后提交后的版本 ANSI 99定义了4种事务隔离级别,SQL Server 2005能够完全支持这些级别: · 未提交读 在读数据时不会检查或使用任何锁。因此,在这种隔离级别中可能读取到没有提交的数据。 · 已提交读 只读取提交的数据并等待其他事务释放排他锁。读数据的共享锁在读操作完成后立即释放。已提交读是 SQL Server 的 默认 隔离级别。 · 可重复读 像已提交读级别那样读数据,但会保持共享锁直到事务结束。 · 可序列化 工作方式类似于可重复读。但它不仅会锁定受影响的数据,还会锁定这个范围。这就阻止了新数据插入查询所涉及的范围,这种情况可以导致幻像读。 此外,SQL