《硬道理》系列~第一回 程序中的“锁”

简介:

共享锁 

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

独占锁和共享锁的区别

1.共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
排他锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
2.Windows中可以有共享锁

3.其它用户可以并发读取,查询数据。但不能修改,增加,删除数据。资源共享.

排它锁(独占锁)


 

排它锁又称为写锁((eXclusive lock,简记为X锁)),若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。在更新操作(INSERT、UPDATE 或 DELETE)过程中始终应用排它锁。

相对于共享锁的区别:

共享锁又称为读锁(Share lock,简记为S锁),若事务T对数据对象A加上S锁,则其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。
C#中的独占锁
  //资源
        static int theResource = 0;
        //读、写操作锁
        static ReaderWriterLock readerWriterLock = new ReaderWriterLock();
        //读数据
        static void Read()
        {
            for (int i = 0; i < 3; i++)
            {
                try
                {
                    //申请读操作锁,如果在1000ms内未获取读操作锁,则放弃
                    readerWriterLock.AcquireReaderLock(1000);
                    Console.WriteLine("开始读取数据,theResource = {0}", theResource);
                    Thread.Sleep(10);
                    Console.WriteLine("读取数据结束,theResource = {0}", theResource);
                    //释放读操作锁
                    readerWriterLock.ReleaseReaderLock();
                }
                catch (ApplicationException)
                {
                    //获取读操作锁失败的处理
                }
            }
        }
static void Main(string[] args)
        {
            //分别创建2个读操作线程,2个写操作线程,并启动
            Thread tr0 = new Thread(new ThreadStart(Read));
            Thread tr1 = new Thread(new ThreadStart(Read));
            Thread tr2 = new Thread(new ThreadStart(Write));
            Thread tr3 = new Thread(new ThreadStart(Write));

            tr0.Start();
            tr1.Start();
            tr2.Start();
            tr3.Start();

            //等待线程执行完毕
            tr0.Join();
            tr1.Join();
            tr2.Join();
            tr3.Join();

            System.Console.ReadKey();
}

本文转自博客园张占岭(仓储大叔)的博客,原文链接:《硬道理》系列~第一回 程序中的“锁”,如需转载请自行联系原博主。

目录
相关文章
|
3月前
|
NoSQL 容器 消息中间件
番外篇 中国古代的操 作系统
番外篇 中国古代的操 作系统
|
2月前
|
Java API 开发者
高逼格面试:线程封闭,新名词√
高逼格面试:线程封闭,新名词√
34 0
|
9月前
|
缓存 Java 程序员
肝到头秃!百度强推并发编程笔记我爱了,原来这才叫并发
随着Java程序员的大幅增长,人们对Java程序员的要求也是越来越严苛。从现在Java岗的招聘需求来看,并发编程已经是我们Java程序员避不开的坎了! 编写正确的程序并不容易,而编写正确的并发程序就更难了。与顺序执行的程序相比,并发程序中显然更容易出现错误。而且并发性错误通常并不会以某种确定的方式显现出来。
|
Java 关系型数据库 MySQL
【浅尝高并发编程】接私活差点翻车
作为一名本本分分的练习时长两年半的Java练习生,一直深耕在业务逻辑里,对并发编程的了解仅仅停留在八股文里。一次偶然的机会,接到一个私活,核心逻辑是写一个 定时访问api把数据持久化到数据库的小服务。
144 0
|
存储 Java 编译器
【高并发趣事二】——JMM及程序中的幽灵
【高并发趣事二】——JMM及程序中的幽灵
67 0
【高并发趣事二】——JMM及程序中的幽灵
|
存储 安全 算法
重生之我在人间敲代码_Java并发基础_安全性、活跃性以及性能问题
并发编程中我们需要注意的问题有很多,很庆幸前人已经帮我们总结过了,主要有三个方面,分别是:安全性问题、活跃性问题和性能问题。
|
Java 编译器 调度
重生之我在人间敲代码_Java并发基础_原子性问题之互斥锁
原子性问题的源头是线程切换,如果能够禁用线程切换那就能解决这个问题。而操作系统做线程切换是依赖 CPU 中断的,所以禁止 CPU 发生中断就能够禁止线程切换。
|
缓存 Java 编译器
重生之我在人间敲代码_Java并发基础_Java内存模型
导致可见性的原因是缓存,导致有序性的原因是编译优化,那解决可见性、有序性最直接的办法就是禁用缓存和编译优化,但是这样问题虽然解决了,我们程序的性能可就堪忧了。
深夜!小胖问我,什么是自旋锁?怎么使用?适用场景是啥?
深夜!小胖问我,什么是自旋锁?怎么使用?适用场景是啥?
深夜!小胖问我,什么是自旋锁?怎么使用?适用场景是啥?