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

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

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

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

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

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

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

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

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

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

HashMap也不是线程安全的

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

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

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

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

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

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

时间: 2024-11-05 19:05:52

软件构造 并发3(线程安全性)的相关文章

软件构造 并发3(线程安全性)----锁定和同步

同步:防止线程同时访问共享数据. 锁:是一种抽象,最多允许一个线程拥有它. 保持锁定是一条线程告诉其他线程的:我正在改变这  个东西,现在不要触摸它 两个操作:获取允许线程获取锁的所有权. 如果一个线程试图获取当前由另一个线程拥有的锁,它将阻塞,直到另一个线程释放该锁. 此时,它将与任何其他尝试获取锁的线程竞争. 一次只能有一个线程拥有该锁.释放锁的所有权,允许另一个线程获得它的所有权 使用锁还会告知编译器和处理器您正在同时使用共享内存,以便将寄存器和高速缓存刷新到共享存储. 这可以确保锁的所有

软件构造 并发1

并发:多个运算同时发生.并发模型:共享内存 消息传递共享内存:并发模块通过在内存中读写共享对象进行交互 ①两个处理器共享物理内存②两个程序共享文件③两个线程(同一个java程序)共享对象 消息传递:并发模块通过通信通道相互发送消息进行交互.模块发送消息,并将传入的消息发送到每个模块以便处理 ①网络中两台计算机通信②web浏览器web server③即时消息的客户端和服务器④通过管道连接两个程序的输入和输出 进程 线程两种不同的并发模块进程:正在运行程序的一个实例,拥有自己私有专用的内存空间   

软件构造 并发2

交织竞争条件在某时刻一个运行核心只有一个线程可以运行.   进程/线程采用OS提供的时间片特征来共享处理时间.当线程数多于处理器数量时,并发性通过时间片来模拟,处理器切换处理不同的线程.例子:时间片(其使用是不可预知的,非确定性的,意味着线程可能随时暂停或恢复)           三个线程T1 T2 T3可能在具有两个实际处理器的机器上进行时间分割,一个处理器运行线程T1,另一个运行线程T2,第二个处理器切换到运行线程T3.                                   

第二章:线程安全性——java并发编程实战

一个对象是否需要是线程安全的取决于它是否被多个线程访问. 当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错.解决办法: 不在线程之间共享该变量 将状态变量修改为不可变的 在访问状态变量时使用同步机制 完全由线程安全类构造的程序也不一定是线程安全的,线程安全类中也可以包含非线程安全的类 一.什么是线程安全性 线程安全是指多个线程在访问一个类时,如果不需要额外的同步,这个类的行为仍然是正确的.(因为线程安全类中封装了必要的同步代码) 一个无状态的类是线程安全的.无状态类是指不

并发基础知识 — 线程安全性

前段时间看完了<并发编程的艺术>,总感觉自己对于并发缺少一些整体的认识.今天借助<Java并发编程实践>,从一些基本概念开始,重新整理一下自己学过并发编程.从并发基础开始,深入进去,系统学习一下并发编程. 编写线程安全的代码,核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问.对象的状态是指存储在状态变量(实例或静态域)中的数据.对象的状态还可能包括其他依赖对象的域.(Map.Entry) 一个对象是否需要时线程安全的,取决于该对象

JAVA并发编程实战 读书笔记(一)线程安全性

线程安全性   1.什么是线程安全 在线程安全的定义中,最核心的概念是正确性.正确性的含义是,某个类的行为与规范完全一致.当对正确性有了一个比较清晰的定义后,就可以定义线程安全性:当多个线程访问某个类时,这个类始终能表现出正确的行为,那这个类就是线程安全的. 举例:无状态对象一定是线程安全的. 大多数Servlet都是无状态的,当Servlet在处理请求时需要保存一些信息时,线程安全才会成为一个问题. 2.原子性 举个例子:语句 ++i:虽然递增操作++i是一种紧凑的语法,使其看上去是一个操作,

并发编程初探-线程安全性

在Java并发编程中,对于线程安全是非常重要的,也是必须要考虑的一个问题.可以这么说,只要涉及到网络的,都必须考虑线程安全问题.好了,开始噼里啪啦地开始敲代码之前,我觉得有必要了解一些文绉绉的理论知识,因为这些理论知识是我们敲出来的代码是否是线程安全的一个依据. 当多个线程访问某个状态变量并且其中有一个线程执行写入操作的时候,必须考虑采用同步机制来协同这些线程对变量的访问,Java中的主要同步机制是关键字synchronized,它提供了一种独占的加锁方式,但"同步"这个术语还包括类型的变量,显

Java并发编程学习笔记(一)——线程安全性

1.当多个线程访问某个状态变量并且其中有一个献策灰姑娘执行写入操作时,必须采用同步机制来协同这些线程对变量的访问.Java中的主要同步机制是关键字synchronized,他提供了一种独占的加锁方式. 2.在任何情况下,只有当类中仅包含自己的状态时,线程安全类才是有意义的. 3.当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些献策灰姑娘讲如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 4.无状态对象一定是线程安全的

《Java并发变成实践》读书笔记---第二章 线程安全性

什么是线程安全性 要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问.从非正式的意义上来说,对象的状态是指存储在状态变量(例如实例或静态域)中的数据."共享"意味着变量可以由多个线程同时访问,而"可变"则意味着变量的值在其生命周期内可以发生变化.所以编写线程安全的代码更侧重于如何防止在数据上发生不受控的并发访问. 如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误