悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 通过 jdbc 实现时 sql 语句只要在整个语句之后加 for update 即可。例如: select …for update

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

两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适

共享锁:(读取)操作创建的锁。其他用户可以并发读取数据,但任何事物都不能获取数据上的排它锁,直到已释放所有共享锁。
共享锁(S锁)又称为读锁,若事务T对数据对象A加上S锁,则事务T只能读A;其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

共享锁的使用

在第一个连接中执行以下语句
begin tran
select * from table1 holdlock -holdlock人为加锁
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran
若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个事务释放共享锁转为排它锁后才能执行 即要等待30秒
 
排它锁:排它锁又称为写锁((eXclusive lock,简记为X锁)),若事物T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。

排它锁的使用

在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran

若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒

互斥锁(Mutex)

互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。

互斥锁可适用于一个共享资源每次只能被一个线程访问的情况

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Threading; namespace MyTTCon
{
class shareRes
{
public static int count = ;
public static Mutex mutex = new Mutex();
} class IncThread
{
int number;
public Thread thrd;
public IncThread(string name, int n)
{
thrd = new Thread(this.run);
number = n;
thrd.Name = name;
thrd.Start();
}
void run()
{
Console.WriteLine(thrd.Name + "正在等待 the mutex");
//申请
shareRes.mutex.WaitOne();
Console.WriteLine(thrd.Name + "申请到 the mutex");
do
{
Thread.Sleep();
shareRes.count++;
Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count);
number--;
} while (number > );
Console.WriteLine(thrd.Name + "释放 the nmutex");
// 释放
shareRes.mutex.ReleaseMutex();
}
}
class DecThread
{
int number;
public Thread thrd;
public DecThread(string name, int n)
{
thrd = new Thread(this.run);
number = n;
thrd.Name = name;
thrd.Start();
}
void run()
{
Console.WriteLine(thrd.Name + "正在等待 the mutex");
//申请
shareRes.mutex.WaitOne();
Console.WriteLine(thrd.Name + "申请到 the mutex");
do
{
Thread.Sleep();
shareRes.count--;
Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count);
number--;
} while (number > );
Console.WriteLine(thrd.Name + "释放 the nmutex");
// 释放
shareRes.mutex.ReleaseMutex();
}
} class Program
{
static void Main(string[] args)
{
IncThread mthrd1 = new IncThread("IncThread thread ", );
DecThread mthrd2 = new DecThread("DecThread thread ", );
mthrd1.thrd.Join();
mthrd2.thrd.Join();
}
}
}

小结:

  悲观锁:查询加锁 【select ...... for update】

  乐观锁:修改加锁 【版本号控制】

  排它锁:事务A可以查询、修改,直到事务A释放为止才可以执行下一个事务

  共享锁:事务A可以查询、修改,同时事务B也可以查询但不能修改

  互斥锁:同一资源同一时间只能被一个线程访问

C# 乐观锁、悲观锁、共享锁、排它锁、互斥锁的更多相关文章

  1. mysql悲观锁中的共享锁和排他锁

    概述: 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改. 排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一 ...

  2. 异步与并行~ReaderWriterLockSlim实现的共享锁和互斥锁

    返回目录 在System.Threading.Tasks命名空间下,使用ReaderWriterLockSlim对象来实现多线程并发时的锁管理,它比lock来说,性能更好,也并合理,我们都知道lock ...

  3. MySQL锁(表锁,行锁,共享锁,排它锁,间隙锁)使用详解

    锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一 ...

  4. [转]MySQL中乐观锁、悲观锁(共享锁、排他锁)简介

    InnoDB与MyISAM Mysql 在5.5之前默认使用 MyISAM 存储引擎,之后使用 InnoDB. MyISAM 操作数据都是使用的表锁,你更新一条记录就要锁整个表,导致性能较低,并发不高 ...

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

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

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

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

  7. 悲观的并发策略——Synchronized互斥锁

    volatile既然不足以保证数据同步,那么就必须要引入锁来确保.互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁 ...

  8. mysql共享锁与排他锁

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  9. posix 匿名信号量与互斥锁 示例生产者--消费者问题

    一.posix 信号量 信号量的概念参见这里.前面也讲过system v 信号量,现在来说说posix 信号量. system v 信号量只能用于进程间同步,而posix 信号量除了可以进程间同步,还 ...

  10. Mysql的共享锁和排他锁(转载)

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

随机推荐

  1. NGUI外包开发总结一下今天的收获

    先总结一下今天的收获:在一个脚本类中对其成员变量进行初始化时,什么时候在Awake()中,什么时候在Start()中是有讲究的. 1)当成员变量会被外部脚本引用时,尤其是该成员变量是一个自己定义的非脚 ...

  2. 第二节 Python基础之变量,运算符,if语句,while和for循环语句

    我们在上一节中,我们发现当我们用字符串进行一些功能处理的时候,我们都是把整个字符串写下来的,比如"jasonhy".startwith("j"),如果我们在程序 ...

  3. Linux环境下使用Android NDK编译c/c++生成可执行文件

    1.安装Android NDK至Linux(Lubuntu 16) 从网上下载 android-ndk-r13b-linux-x86_64.zip,本人将其解压至/home/guanglun/work ...

  4. H264--2--语法及结构

    转自:http://blog.csdn.net/yangzhongxuan/article/details/8003494 名词解释 场和帧 :    视频的一场或一帧可用来产生一个编码图像.在电视中 ...

  5. shell脚本命令远程连接ssh并执行命令

    环境: redhat 6.5 根据网上提供方法,测试了很多写法都不成功,测试了很久才有了以下脚本. 命令远程连接ssh并执行命令,scp/ftp等远程连接操作同理: #!/usr/bin/expect ...

  6. Linux 版 SecureCRT 界面变为 Windows 2000 风格的解决办法

    SecureCRT 是一款非常好用的远程终端连接软件,支持 Windows.Linux.macOS 全平台.由于现在工作平台主要在 Linux 系统上,SecureCRT 也是必备软件.一开始安装的是 ...

  7. redis过期机制(官网文档总结)

    官网地址:https://redis.io/commands/expire redis过期定义如下: Set a timeout on key. After the timeout has expir ...

  8. https://www.oschina.net/project/lang/19/java

    https://www.oschina.net/project/lang/19/java

  9. Python全栈开发记录_第五篇(装饰器)

    单独记录装饰器这个知识点是因为这个知识点是非常重要的,必须掌握的(代码大约150行). 了解装饰器之前要知道三个知识点 作用域,上一篇讲到过顺序是L->E->G->B 高阶函数: 满 ...

  10. eclipse的常用设置(空间新建后需要的配置)

    地址:https://blog.csdn.net/qiaorui_/article/details/78424491 说明:              新下载的eclipse或者新建了一个工作空间,之 ...