线程与锁模型的优缺点锁与共享内存例子以及解决方案

2018-02-10  本文已影响102人  每天学点编程

请关注我的微信公众号

个人微信公众号

技术交流群 (仅作技术交流):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包是更好的选择。

上一篇下一篇

猜你喜欢

热点阅读