锁机制是解决数据库并发问题最常用的手段之一,你知道锁中轻量级锁及互斥锁分别是什么概念吗?小编下面就为你讲解讲解。
互斥锁
当多线程在一个时间段几乎同时修改某个共享数据的时,需要进行同步控制,这时,线程同步就可以保证多线程安全访问竞争资源,最简单的同步机制就是引入互斥锁。
互斥锁为资源引入一个状态:锁定/非锁定
当前某个线程需要更改共享数据时,先把它锁定,这时资源状态为“锁定”,其他线程均不可更改数据;直到这个线程释放资源,资源状态变为“非锁定”,其余线程才能再次锁定该资源。互斥锁机制保证了每次只能有一个线程进行写入操作,从而保证了在多线程情况下数据的正确性。
实现:使用互斥锁完成多线程对同个全局变量各增加100万次的操作
import threadingimport time g_num = 0 def test1(num): global g_num for i in range(num): mutex.acquire()# 上锁 g_num += 1 mutex.release()# 解锁 print("---test1---g_num=%d" % g_num) def test2(num): global g_num for i in range(num): mutex.acquire()# 上锁 g_num += 1 mutex.release()# 解锁 print("---test2---g_num=%d" % g_num)# 创建一个互斥锁# 默认是未上锁的状态 mutex = threading.Lock()# 创建2个线程, 让他们各自对g_num加1000000次 p1 = threading.Thread(target = test1, args = (1000000, )) p1.start() p2 = threading.Thread(target = test2, args = (1000000, )) p2.start()# 等待计算完成while len(threading.enumerate()) != 1: time.sleep(1) print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
运行结果:
---test1---g_num=1909909 ---test2---g_num=20000002个线程对同一个全局变量操作之后的最终结果是:2000000
轻量级锁
轻量级锁准确的说不是传统意义上的锁,它是锁的一种状态,它是偏向锁的升级,偏向锁在运行一个线程进入同步块的情况下,第二个锁进入争抢,偏向锁就会升级为轻量级锁。
轻量级锁通常也被叫做非阻塞同步、乐观锁,因为在它执行的这个过程并没有把线程阻塞挂起,反而让线程空循环等待,串行执行。
使用轻量级锁能够最大化减少性能消耗,但有个缺点,一旦多个线程同时竞争锁时,轻量级锁就会膨胀,成为重量级锁。
轻量级锁主要有两种:a自旋锁b自适应自旋锁
以上就是本篇文章的所有内容了,如果小伙伴们还需要了解更多锁相关常见问题,就一直关注我们吧。
推荐阅读: