加入收藏 | 设为首页 | 会员中心 | 我要投稿 阜阳站长网 (https://www.0558zz.cn/)- AI行业应用、低代码、混合云存储、数据仓库、物联网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

安全性、活跃性以及性能问题

发布时间:2021-03-24 15:59:51 所属栏目:外闻 来源:互联网
导读:能写出线程安全的程序呢?在上一篇中已经介绍了并发 Bug 的三个主要源头:原子性问题、可见性问题和有序性问题。也就是说,理论上线程安全的程序,就要避免出现原子性问题、可见性问题和有序性问题。 那是不是所有的代码都需要认真分析一遍是否存在这三个问题

能写出线程安全的程序呢?在上一篇中已经介绍了并发 Bug 的三个主要源头:原子性问题、可见性问题和有序性问题。也就是说,理论上线程安全的程序,就要避免出现原子性问题、可见性问题和有序性问题。

那是不是所有的代码都需要认真分析一遍是否存在这三个问题呢?当然不是,其实只有一种情况需要:存在共享数据并且该数据会发生变化,通俗地讲就是有多个线程会同时读写同一数据。那如果能够做到不共享数据或者数据状态不发生变化,不就能够保证线程的安全性了嘛。有不少技术方案都是基于这个理论的,例如线程本地存储(Thread Local Storage,TLS)、不变模式等等,后面我会详细介绍相关的技术方案是如何在 Java 语言中实现的。

但是,现实生活中,必须共享会发生变化的数据,这样的应用场景还是很多的。

当多个线程同时访问同一数据,并且至少有一个线程会写这个数据的时候,如果我们不采取防护措施,那么就会导致并发 Bug,对此还有一个专业的术语,叫做数据竞争(DataRace)。比如,前面这篇文章里有个 add10K() 的方法,当多个线程调用时候就会发生数据竞争,如下所示。
那是不是在访问数据的地方,我们加个锁保护一下就能解决所有的并发问题了呢?显然没有这么简单。例如,对于上面示例,我们稍作修改,增加两个被 synchronized 修饰的 get()和 set() 方法, add10K() 方法里面通过 get() 和 set() 方法来访问 value 变量,修改后的代码如下所示。对于修改后的代码,所有访问共享变量 value 的地方,我们都增加了互斥锁,此时是不存在数据竞争的。但很显然修改后的 add10K() 方法并不是线程安全的。

(编辑:阜阳站长网)

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

    热点阅读