做编程的,不可避免的会遇到各种各样的锁。
通常锁伴随多线程技术而来,为了保证多线程甚至多进程环境下资源的并发安全性,我们需要给资源加锁,避免多个线程/进程同时操作同一个资源。
真实工作中也接触了各种各样的锁,有乐观锁悲观锁,有共享锁独占锁,有读写锁,有可重入锁不可重入锁等等。面对这么多锁概念,有时候真的分不清。
蛋蛋尝试从最基本的概念来描述锁,然后慢慢展开,研究java锁、数据库锁、分布式锁。相信最后,读者能从中看到锁的本质,从根源理解锁,并会应用锁。
程序中的锁和现实生活中的锁还有点儿不一样。
现实生活中一个人把门锁上把钥匙拿走了,那另外的人就真的进不去了。而程序中的锁要想别的线程/进程进不来,通常需要别的线程/进程也有获取锁的代码,当获取不到锁不能继续往下走。
如果你没有这段代码,你还是可以继续访问共享资源的。所以从这个点来说,程序中的锁它其实是一种需要自发遵守的约定。
所以很多时候有新手玩家会问,我明明在这里加锁了,为什么那里的线程还是能访问到资源呢?
那是因为你没有遵守获取锁的约定,它不是强制的,它需要你的代码按照一定的格式来编排,才能获取不到锁。
写程序的时候,我们需要在该加锁的地方加锁,但是更重要的是在该锁住的地方要锁住。
今日份总结:程序中的锁不是强制性的,代码漏洞、代码疏忽完全可以绕过锁,它更多的是一个写代码的约定。