码迷,mamicode.com
首页 > 编程语言 > 详细

软件构造 并发3(线程安全性)

时间:2018-06-18 23:17:40      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:突变   前置   通过   副本   相同   避免   破坏   数据类型   生命周期   

线程安全:数据类型或静态方法在多线程中执行时,无论如何执行,不需调用者做额外的协作仍可以得到正确的行为。

                 行为正确意味着满足规格说明和保持不变性   不能在前置条件中对调用者增加时间性要求(在set()运行时不能调用get())

                 例子:迭代器, 不是线程安全的。 迭代器的规范说,不能在迭代它的同时修改一个集合。 这是一个与调用者相关的时间相关的前提条件,如果违反它,Iterator不保证行为正确

线程安全的四个方法:①限制可变变量的共享②用不可变的共享变量③将共享数据封装在线程安全的数据类型中④使用同步来防止线程同时访问变量

限制可变变量的共享:通过将数据限制在单个线程中,可以避免线程在可变数据上进行竞争。可变量的共享是竞争的主要原因

                                   ①局部变量保存在线程栈中,每个调用都有自己的变量副本 ,每个线程都有自己的堆栈。

                                   ②局部变量如果是对象的引用,则要确保不能引用任何其他线程可访问 的对象。

                                   避免全局变量:全局静态变量不会自动受到线程访问限制。如果使用了全局静态变量,应说明只有一个线程会使用它们。最好在多线程环境中取消全局静态变量

                                   两个线程若同时调用一个返回类的公众静态方法,会产生两个实例,破坏了表示不变性。改造:采用限制的方式并自行确保只有一个线程访问该方法;采用synchronized方式

                                   HashMap也不是线程安全的

用不可变的共享变量:使用不可变的引用和数据类型。不可变解决了因为共享可变数据造成的竞争,并简单地通过使共享数据不可变来解决它。

                                    final变量是不可变的引用,所以声明为final的变量可以安全地从多个线程访问。(只能读不能写   因为这种安全性只适用于变量本身,仍然必须确保变量指向的对象是不可变的)

                                   回忆不变性:类型是不可变的:如果类型的对象在其整个生命周期中始终表示相同的抽象值

                                                         但实际上,允许对rep进行改变,只要这些改变对客户是不可见的,并且对应的抽象值不变(有益的突变)但是对于并发性,这种隐藏的变化是不安全的 , 使用有益的变  

                                                         化的不可变数据类型必须使用锁使自己线程安全。

软件构造 并发3(线程安全性)

标签:突变   前置   通过   副本   相同   避免   破坏   数据类型   生命周期   

原文地址:https://www.cnblogs.com/xgl122/p/9196640.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!