加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡水站长网 (https://www.0318zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

传统编程模型存在的问题

发布时间:2021-03-16 14:57:12 所属栏目:外闻 来源:互联网
导读:必须通过对象提供的一系列方法来间接进行访问。对象负责公开对数据的安全操作的方法,以保护其封装的数据的不变性。 在多线程下,多个线程同时调用同一个对象的方法来修改其内部封装的数据时候,就会存在线程安全问题,这是因为封装本身不确保对象内部数据的

必须通过对象提供的一系列方法来间接进行访问。对象负责公开对数据的安全操作的方法,以保护其封装的数据的不变性。

在多线程下,多个线程同时调用同一个对象的方法来修改其内部封装的数据时候,就会存在线程安全问题,这是因为封装本身不确保对象内部数据的一致性,在不对对象的方法在修改数据施加一定同步措施时,对象内的数据就会在多线程访问下变得不确定了。

一个解决该问题的方式就是,多线程访问对象方法内数据时候施加一定同步措施,比如加锁,加锁可以保证同时只有一个线程可以访问对象内的数据,但是加锁会带来昂贵的代价:

  • 使用锁会严重影响并发度,使用锁在现在CPU架构中是一个比较昂贵的操作,因为当线程获取锁失败后会把线程从用户态切换到内核态把线程挂起,稍后唤醒后又需要从内核态切换到用户态进行运行。
  • 获取锁失败的调用线程会被阻塞挂起,因此它不能做任何有意义的事情。即使在桌面应用程序中这也是不可取的,我们想要的是即使后台有一个运行比较耗时的工作在运行,也要保证系统对用户的一部分请求有响应。在后端应用中,阻塞是完全浪费资源的。另外可能有人认为虽然当前线程阻塞了,但是我们可以通过启动新线程来弥补这一点,但是需要注意一点,线程也是一种昂贵的资源,操作系统对线程个数是有限制的。
  • 另外锁的存在,带来了新的威胁,即死锁问题的存在。

由于以上问题的存在,导致我们进退两难:

  • 如果不使用足够的锁,则不能保证多线程下对象中数据不受到破坏。
  • 如果在对象中每个数据访问是都加了锁,则会导致系统性能下降,并且很容易导致死锁的发生。

另外,锁只能在单JVM内(本地锁)很好的工作。当涉及到跨多台机协调时,只能使用分布式锁。但是分布式锁的效率比本地锁低几个数量级,这是因为分布式锁协议需要跨多台机在网络上进行多次往返通信,所以其造成较大的影响就是延迟。

小结:

  • 对象只能在单线程情况下保证封装的安全性,也就是保证对象封装的数据的线程安全性。多线程下修改对象内的数据大多情况下会导致数据被污染,造成脏数据产生。在同一代码段中有两个竞争线程会导致违反每个不变式。
  • 虽然锁看起来是保证多线程下封特性比较直接的方式,但实际上使用锁的效率低下,并且在任何实际规模的应用中都容易导致死锁的产生。
  • 本地锁是我们经常使用的,但是如果尝试将其扩展为分布式锁,则是有代价的,并且其横向扩展的潜力有限。

(编辑:衡水站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读