悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,因此每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了不少这种锁机制,好比行锁,表锁等,读锁,写锁等,都是在作操做以前先上锁。 经过 jdbc 实现时 sql 语句只要在整个语句以后加 for update 便可。例如: select …for updatesql
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可使用版本号等机制。乐观锁适用于多读的应用类型,这样能够提升吞吐量,像数据库若是提供相似于write_condition机制的其实都是提供的乐观锁。数据库
两种锁各有优缺点,不可认为一种好于另外一种,像乐观锁适用于写比较少的状况下,即冲突真的不多发生的时候,这样能够省去了锁的开销,加大了系统的整个吞吐量。但若是常常产生冲突,上层应用会不断的进行retry,这样反却是下降了性能,因此这种状况下用悲观锁就比较合适并发
在第一个链接中执行如下语句
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)this
互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程能够获取它。spa
互斥锁可适用于一个共享资源每次只能被一个线程访问的状况线程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace MyTTCon { class shareRes { public static int count = 0; 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(1000); shareRes.count++; Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count); number--; } while (number > 0); 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(1000); shareRes.count--; Console.WriteLine("In " + thrd.Name + "ShareRes.count is " + shareRes.count); number--; } while (number > 0); Console.WriteLine(thrd.Name + "释放 the nmutex"); // 释放 shareRes.mutex.ReleaseMutex(); } } class Program { static void Main(string[] args) { IncThread mthrd1 = new IncThread("IncThread thread ", 5); DecThread mthrd2 = new DecThread("DecThread thread ", 5); mthrd1.thrd.Join(); mthrd2.thrd.Join(); } } }
小结:code
悲观锁:查询加锁 【select ...... for update】对象
乐观锁:修改加锁 【版本号控制】blog
排它锁:事务A能够查询、修改,直到事务A释放为止才能够执行下一个事务
共享锁:事务A能够查询、修改,同时事务B也能够查询但不能修改
互斥锁:同一资源同一时间只能被一个线程访问