请关注我的微信公众号
个人微信公众号
技术交流群 (仅作技术交流):642646237
请关注我的头条号:
线程与锁模型的优缺点
线程与锁模型其实是对底层硬件运行过程的形式化。这种形式化既是该模型最大的优点,也是它最大的缺点。
线程与锁模型非常简单直接,几乎所有编程语言都以某种形式对其提供了支持,且不对其使用方式加以限制。
编程语言没有提供足够的帮助,使得程序容易出错且难以维护。
建议
不应在产品代码上直接使用Thread
类等底层服务。
互斥概念
互斥——用锁保证某一时间仅有一个线程可以访问数据(使用共享内存)。
锁与共享内存
使用锁达到线程互斥的目的,即某一时间至多有一个线程能持有锁。
锁与共享内存——例子
运行这段代码,每次都将获得不同的结果。
产生这个结果的原因是两个线程使用counter.count
对象时发生了竞态条件(即代码行为取决于各操作的时序)。
锁与共享内存——++count
字节码
getfield #2用于获取count的值,iconst_1和iadd将获得的值加1,putfield #2将更新的值写回count中。这就是读-改-写(read-modify-write)模式。
锁与共享内存——例子每次可能得到不同结果的原因
线程1执行getfield #2,这时线程1暂停执行,线程2也执行了getfield #2,现在两个线程都将获得的值加1,并将值写回count中。结果count只被递增了一次,而不是两次。
锁与共享内存——解决例子每次可能得到不同结果的问题
竞态条件的解决方案是对count进行同步(synchronize)访问。
使用Java对象原生的内置锁(互斥锁(mutex)、管程(monitor)或临界区(critical section))来同步increment()
线程进入increment()函数时,将获取Counter对象级别的锁,函数返回时将释放该锁。某一时间至多有一个线程可以执行函数体,其他线程调用函数时将被阻塞直到锁被释放
锁与共享内存——另外的解决方案
对于这种只涉及一个变量的互斥场景,使用java.util.concurrnet.atomic包是更好的选择。
网友评论