`
lvhuiqing
  • 浏览: 256737 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

2.4. Guarding State with Locks(使用锁维护状态)

阅读更多
2.4. Guarding State with Locks(使用锁维护状态)
Because locks enable serialized [8] access to the code paths they guard, we can use them to construct protocols for guaranteeing exclusive access to shared state. Following these protocols consistently can ensure state consistency.
由于锁机制可以保证对他们所保护的代码路径的序列化访问,我们可以使用锁机制来建立保证对共享状态的独占式访问。只要遵循这些协议,就可以保证状态的一致性。
[8] Serializing access to an object has nothing to do with object serialization (turning an object into a byte stream); serializing access means that threads take turns accessing the object exclusively, rather than doing so concurrently.
序列化的访问一个类与类的序列化没有一点儿关系(把一个类变成字节流),序列化的访问意味着线程独占式的轮流访问对象,而不是并发的访问。
Compound actions on shared state, such as incrementing a hit counter (read-modify-write) or lazy initialization (check-then-act), must be made atomic to avoid race conditions. Holding a lock for the entire duration of a compound action can make that compound action atomic. However, just wrapping the compound action with a synchronized block is not sufficient; if synchronization is used to coordinate access to a variable, it is needed everywhere that variable is accessed. Further, when using locks to coordinate access to a variable, the same lock must be used wherever that variable is accessed.
共享状态的复合行为,比如增加一个“点击计数”、或者延迟初始化,都必须被设置成原子化的来避免条件竞争。对整个复合行为加上锁机制,就可以把复合锁变成原子的。但是,仅仅把复合行为加上锁机制还是不够的,如果同步机制被用来协调访问一个可变因素,那么在可变因素可以被访问的任何地方,同步机制都必须存在。进一步说,当使用锁来管理对可变因素的访问的时候,那么这把锁就应该应用在任何可变因素可以被访问的地方。
It is a common mistake to assume that synchronization needs to be used only when writing to shared variables; this is simply not true. (The reasons for this will become clearer in Section 3.1.)
有一个非常普遍的错误认为只有在写入共享变量的时候,同步机制才是必须的,这种想法是错误(错误的原因在第3.1节中)。
For each mutable state variable that may be accessed by more than one thread, all accesses to that variable must be performed with the same lock held. In this case, we say that the variable is guarded by that lock.
由于每个可变的状态变量可能会被多个线程访问,所有对变量的访问都必须被同一把锁管理。在这种情况下,我们说变量被那把锁守护。

In SynchronizedFactorizer in Listing 2.6, lastNumber and lastFactors are guarded by the servlet object's intrinsic lock; this is documented by the @GuardedBy annotation.
在SynchronizedFactorizer中,lastNumber和lastFactors被servlet对象的内在锁守护。
There is no inherent relationship between an object's intrinsic lock and its state; an object's fields need not be guarded by its intrinsic lock, though this is a perfectly valid locking convention that is used by many classes. Acquiring the lock associated with an object does not prevent other threads from accessing that object the only thing that acquiring a lock prevents any other thread from doing is acquiring that same lock. The fact that every object has a built-in lock is just a convenience so that you needn't explicitly create lock objects. [9] It is up to you to construct locking protocols or synchronization policies that let you access shared state safely, and to use them consistently throughout your program.
[9] In retrospect, this design decision was probably a bad one: not only can it be confusing, but it forces JVM implementors to make tradeoffs between object size and locking performance.
在对象的内在锁和状态之间没有内在的联系。一个对象的状态不是必须被他本身的内在锁守护,尽管这种保护方式是一种被很多类所使用的正确方式。拥有与对象关联的锁并不会阻止其他线程访问该对象,拥有锁后唯一能够确保的事情是可以组织其余线程去获取锁。每个对象都有一把内在锁仅仅是为了让你不必去显示的创建一个锁对象。现在你可以来创建锁协议或者同步策略来安全的共享状态了,并且你要在你的整个程序中持续使用。
回顾起来,这个设计决定是非常糟糕的,这不仅容易让人迷惑,而且使得JVM的实现者不得不在对象尺寸和锁的性能上作出取舍。
Every shared, mutable variable should be guarded by exactly one lock. Make it clear to maintainers which lock that is.
每一个共享的,可变的变量都应该被一把锁来守护。应该对维护者说明使用那把锁。
A common locking convention is to encapsulate all mutable state within an object and to protect it from concurrent access by synchronizing any code path that accesses mutable state using the object's intrinsic lock. This pattern is used by many thread-safe classes, such as Vector and other synchronized collection classes. In such cases, all the variables in an object's state are guarded by the object's intrinsic lock. However, there is nothing special about this pattern, and neither the compiler nor the runtime enforces this (or any other) pattern of locking. [10] It is also easy to subvert this locking protocol accidentally by adding a new method or code path and forgetting to use synchronization.
一个常见的锁机制使用惯例是把所有的可变状态封装入一个对象中,然后通过对象的内在锁来同步对可变状态访问来保护并发访问。这种方法被很多现成安全的类使用,比如Vector,和其他同步容器类。这些场景中,一个对象中所有状态都被对象的内在锁保护。但是,这种模式并没有特别之处,编译器和运行时环境都不会强制使用这种方式。通过增加一个新的方法或者代码或者忘记使用synchronized关键都很容易破坏这种锁协议。
[10] Code auditing tools like FindBugs can identify when a variable is frequently but not always accessed with a lock held, which may indicate a bug.
向FindBugs这样的代码审查工具会检查出一个频繁被锁保护,但是不总是被锁保护的变量。因为这通常意味着一个bug。
Not all data needs to be guarded by locks only mutable data that will be accessed from multiple threads. In Chapter 1, we described how adding a simple asynchronous event such as a TimerTask can create thread safety requirements that ripple throughout your program, especially if your program state is poorly encapsulated. Consider a single-threaded program that processes a large amount of data. Single-threaded programs require no synchronization, because no data is shared across threads. Now imagine you want to add a feature to create periodic snapshots of its progress, so that it does not have to start again from the beginning if it crashes or must be stopped. You might choose to do this with a TimerTask that goes off every ten minutes, saving the program state to a file.
并不是所有的数据都需要被锁守护,只有可变的、而且会被多线程访问的数据才需要。在第一章中,我们描述了如果在你的应用程序中加入一个简单的异步事务(比如TimerTask),可能会导致你的整个程序面临着线程安全的需求。尤其是,当你的程序状态封装的很差的话。单线程的应用程序不需要同步,因为没有数据在线程间共享。现在想象一下,如果你想创建一个获得进程周期性快照的特性,这样在进程失败或者被停止的情况下,你就不必重新开始。你可以选择使用一个每隔十分钟进行一次的TimerTask来进行,并且把程序状态放入文件。
Since the TimerTask will be called from another thread (one managed by Timer), any data involved in the snapshot is now accessed by two threads: the main program thread and the Timer tHRead. This means that not only must the TimerTask code use synchronization when accessing the program state, but so must any code path in the rest of the program that touches that same data. What used to require no synchronization now requires synchronization throughout the program.
由于TimerTask可能会被其他线程调用(或者被Timer管理),所有涉及到快照的数据都有可能会被两个线程访问:主线程和Timer线程。这就意味着不仅TimerTask访问程序状态的代码需要同步机制,原来程序关联到相同数据的都需要同步机制。这样一来原来对同步机制没有需求变成需要在整个程序的范围内需要同步机制。
When a variable is guarded by a lock meaning that every access to that variable is performed with that lock held you've ensured that only one thread at a time can access that variable. When a class has invariants that involve more than one state variable, there is an additional requirement: each variable participating in the invariant must be guarded by the same lock. This allows you to access or update them in a single atomic operation, preserving the invariant. SynchronizedFactorizer demonstrates this rule: both the cached number and the cached factors are guarded by the servlet object's intrinsic lock.
当一个变量被一个锁守护的时候,这意味着对变量的每次访问都拥有了你指定的锁。当一个类的一致性涉及到超过一个状态变量时,这就有了一个附加需求。每一个参与到一致性中的变量都必须被同一把锁守护。这就要求你在同一个原子操作中访问或者修改它们。SynchronizedFactorizer展示了这样的规则:被缓存的数值和被缓存的因数都被servlet的内在锁对象守护。
For every invariant that involves more than one variable, all the variables involved in that invariant must be guarded by the same lock.
对于涉及到多个变量的不变性,所有变量都必须被同一把锁守护。

If synchronization is the cure for race conditions, why not just declare every method synchronized? It turns out that such indiscriminate application of synchronized might be either too much or too little synchronization. Merely synchronizing every method, as Vector does, is not enough to render compound actions on a Vector atomic:
if (!vector.contains(element))
    vector.add(element);
如果同步机制是用来解决条件竞争,那么为什么不把所有方法都变成同步的呢?事实证明这种不分好坏的同步机制没有半点作用,要么同步机制太多,要么太少。仅仅把每一个方法都同步化(像Vector那样做)并不能保证将复合操作都放在一个Vector原子操作中。
This attempt at a put-if-absent operation has a race condition, even though both contains and add are atomic. While synchronized methods can make individual operations atomic, additional locking is required when multiple operations are combined into a compound action. (See Section 4.4 for some techniques for safely adding additional atomic operations to thread-safe objects.) At the same time, synchronizing every method can lead to liveness or performance problems, as we saw in SynchronizedFactorizer.
尽管保存和增加都是原子的,这种put-if-absent的操作还是存在条件竞争。尽管同步方法使得单独的操作是原子的,当多个操作合并成一个复合操作的时候,附加的锁还是需要的(第4.4节中,展示了向线程安全的对象中增加原子操作的方法)。同时,把每一个方法都同步化会导致存活性和性能问题,就像我们在SynchronizedFactorizer类中看到的那样。
0
0
分享到:
评论

相关推荐

    悬索大振幅三维自由振动中的非线性耦合与动态张力研究(可复现,有问题请联系博主)

    内容概要:本文通过建立严格的数学模型并结合虚拟功能量法,推导了用于分析任意悬垂弹性缆绳大振幅自由振动的三维非线性方程组。所提出的多自由度模型考虑了轴向变形效应以及动态张力响应特性,不仅适用于小挠跨比条件,还能处理显著初始挠曲情况。研究通过数值仿真方法揭示了几何非线性和内部共振现象对缆索动力行为的重要影响,特别探讨了对称和平面对称模态之间的耦合作用及其引起的动力特性变化。 适用人群:工程力学专业人员、土木工程项目研究人员、结构工程师等,尤其涉及大型桥梁及高层建筑中缆索系统的动态特性的分析与设计的专业人士。 使用场景及目标:通过对特定初位移条件下电缆系统的非线性动态响应进行建模与模拟,能够帮助工程师预测和优化电缆系统的运动轨迹,同时为理解复杂环境下如强风或者地震荷载下的桥梁等基础设施提供理论支持。 其他说明:研究成果有助于指导实际应用中关于如何减轻因共振而导致的结构破坏风险的问题;并指出未来工作中需要进一步探索的方向,例如改进现有的简化假设来更好地适应实际工况。

    Python爬虫实例,一个简单的DEMO

    使用requests和BeautifulSoup库爬取豆瓣电影Top250的基本信息

    ISO 8015-2011 英文-中文对照 产品几何技术规范( GPS ) 基础概念、原则和规则 .rar

    标题中的“ISO 8015-2011”是指国际标准化组织(International Organization for Standardization)在2011年制定的一项标准,该标准是关于产品几何技术规范(Geometrical Product Specifications, 简称GPS)的一部分。GPS是工业界用于定义和控制产品几何尺寸和形状的一系列准则,旨在确保产品的设计、制造和检测过程中的精确性和一致性。 “基础概念、原则和规则”这部分内容涵盖了ISO 8015的核心理念,包括但不限于: 1. 几何公差:ISO 8015解释了如何定义和应用几何公差,这是控制产品几何特性的重要手段。它涉及尺寸公差、形状公差、位置公差、方向公差和跳动公差等。 2. 尺寸基准:标准介绍了选择和定义尺寸基准的重要性,这些基准用于确定零件或组件的定位和测量参考。 3. 形状和位置关系:ISO 8015阐述了如何理解和表达零件表面的形状以及它们之间的位置关系,比如平面度、圆度、直线度、平行度、垂直度等。 4. 公差带:公差带是允许几何特性变化的区域,标准中详细规定了如何定义和图解公差带。 5. 控制方法:标准涵盖了各种几何特性的测量和控制方法,如接触测量、光学测量、三坐标测量机(CMM)的应用等。 6. 符号和注释:ISO 8015规定了标准的图形符号和注释方式,以便于设计者和制造者清晰地传达几何要求。 7. 可接受性准则:标准提供了判断产品是否符合几何公差要求的准则,包括最大实体条件(MMC)、最小实体条件(LMC)和其他补偿原则。 “英文-中文对照”表明这份文档提供了双语对照,方便中国用户理解和应用这个国际标准,从而提升国内产品设计和制造的质量。 尽管压缩包中包含的“1.bat”和“一键改名.bat”文件与主题内容直接关联性不强,但它们可能是辅助工具,例如批量修改文件名的脚本,帮助用户更方便地管理和使用ISO 8015的相关资料。 ISO 8015-2011是一个关于产品几何技术规范的重要标准,对工程设计、质量控制和制造流程有着深远影响。理解并应用这些原则和规则能够提高产品的精度和可靠性,降低生产成本,增强市场竞争力。。内容来源于网络分享,如有侵权请联系我删除。

    2025 年全球产品库存数据集(10K+记录,14特征)CSV

    该数据集提供了产品库存的详细快照,非常适合物流优化、电子商务分析或供应链研究。它包括关键详细信息,如产品名称、类别、价格、库存数量等,这些详细信息来自一个假设的全球供应商数据库。我在从事货运物流优化项目时编译了这个,我希望它对其他探索类似挑战的人有用! 主要特点: 14 列,涵盖商品规格、定价、库存和标签。 示例数据包括 Home Appliances 等多个类别。 非常适合数据清理实践、可视化或预测建模(例如,库存耗尽)。 可能的用例: 根据库存和有效期优化货运物流。 分析不同产品类别的定价趋势。 使用标签和评级构建推荐系统。 笔记: 日期范围从制造到到期(例如,2023-2026 年)。 某些字段(例如,产品描述)可能需要改进 - 请随时对其进行改进! 欢迎对其他数据或改进提出建议。 让我知道您如何使用它 - 我很想听听您的反馈! 列描述 Product ID:这是分配给数据集中每个产品的唯一标识符,如“93TGNAY7”。它有助于区分一项与另一项。 Product Name(商品名称):商品的名称,例如 “Laptop”(笔记本电脑)。这是项目是什么的简单标签。 Product Category(商品类别): 这告诉您商品属于哪个类别,例如“Home Appliances”(家用电器)。它将相似的项目分组在一起。 Product Description(商品描述):商品的简要描述。在示例中,它列为“Product_XU5QX”,这可能是一个占位符 - 请随意将其替换为更有意义的内容! 价格: 商品的价格(以美元为单位),例如 253.17。它显示每件物品的价值。 库存数量: 当前有货的商品数量,例如 3。它对于跟踪库存水平非常有用。 保修期:产品的保修期,以年为单位,例如 2。它表示所提供的支持期限。 商品尺寸: 商品的实际尺寸(以厘米为单位),写为“16x15x15 厘米”(长 x 宽 x 高)。这有助于物流和存储规划。 生产日期: 商品的生产日期,例如“2023-01-01”。它便于跟踪产品年龄。 有效期: 商品到期时间(如适用),例如“2026-01-01”。这对于管理保质期非常有用。 SKU:库存单位的缩写,这是类似于“8NMFZ4”的代码,用于在库存系统中跟踪产品。 商品标签: 描述商品的标签列表(以逗号分隔),例如“VNU,NZ6”。这些可以表示功能、关键字或类别。 颜色/尺寸变体: 商品的可用颜色和尺寸,例如“绿色/大号”。它显示了客户可以选择的选项。 商品评分: 买家评分(满分 5 分),例如 2。它反映了反馈或质量感知。

    灵通LD3000 dmr对讲机写频软件

    灵通LD3000 dmr对讲机写频软件

    基于Wav2Lip384的AI主播项目整合包

    开源项目整合包 更多内容可以查阅 项目源码搭建介绍: 《我的AI工具箱Tauri+Django开源git项目介绍和使用》https://datayang.blog.csdn.net/article/details/146156817 图形桌面工具使用教程: 《我的AI工具箱Tauri+Django环境开发,支持局域网使用》https://datayang.blog.csdn.net/article/details/141897682

    Java项目,二手资源交易系统,欢迎学习

    Java项目,二手资源交易系统,欢迎学习。

    基于springboot框架的基于Javaweb的电影院购票系统的设计与实现(Java项目编程实战+完整源码+毕设文档+sql文件+学习练手好项目).zip

    传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装电影院购票系统软件来发挥其高效地信息处理的作用,可以规范信息管理流程,让管理工作可以系统化和程序化,同时,电影院购票系统的有效运用可以帮助管理人员准确快速地处理信息。 电影院购票系统在对开发工具的选择上也很慎重,为了便于开发实现,选择的开发工具为Eclipse,选择的数据库工具为Mysql。以此搭建开发环境实现电影院购票系统的功能。其中管理员管理用户,新闻公告。 电影院购票系统是一款运用软件开发技术设计实现的应用系统,在信息处理上可以达到快速的目的,不管是针对数据添加,数据维护和统计,以及数据查询等处理要求,电影院购票系统都可以轻松应对。 关键词:电影院购票系统;SpringBoot框架,系统分析,数据库设计

    【毕业设计】基于uniapp微信小程序志愿者活动报名在线试卷考试系统【源码+论文+答辩ppt+开题报告+任务书】.zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。

    SAP SD-Class 17 SAP Error Message numbers and controls.mp4

    SAP SD-Class 17 SAP Error Message numbers and controls.mp4

    网络安全中CSRF与XSS攻击及其防护措施详解

    内容概要:本文主要介绍了两种重要的网络攻击手段——CSRF(跨站请求伪造)和XSS(跨站脚本攻击)。首先阐述了CSRF的定义、形成机制以及防范办法,其中包括设置Cookie属性SameSite值为严苛级别或者验证来源请求头部字段Referer/Origin;再介绍了一次性和敏感业务的两步确认法以及采用非Cookie形式的身份标识Token。关于XSS,文中详述三种具体表现形式即存储型、反射型与基于DOM的XSS,还讲解了应对这种风险的有效举措,例如检验与编码用户提交的信息,在服务器回应客户端的数据里加入相关保护性HTTP首部字段,选择更为保险的DOM API接口调用方式以及对Cookies采取额外安全性设定。 适用人群:从事信息安全维护工作的专业人员,尤其涉及Web应用防护的技术团队成员。 使用场景及目标:当用户构建自己的web应用程序时,理解和掌握这两种威胁的运作机理有助于提高自身项目抵御此类恶意行为的能力,保证用户数据安全。 其他说明:了解如何有效地预防这两种类型的攻击不仅对提升个人技能有帮助,同时也能增强所开发系统的健壮性。由于互联网环境复杂多变,不断关注最新的攻防动态十分必要。

    Invoke-WmiCommand.zip

    Invoke-WmiCommand

    CNN-master.zip

    CNN相关以及垃圾分类数据集

    01 DNS DHCP Telnet综合实验 毛佳宇(1).docx

    01 DNS DHCP Telnet综合实验 毛佳宇(1).docx

    建模大赛-风电机组强非线性气动特性拟合建模: 基于神经网络和多项式算法的精确快速计算方案

    建模大赛-风电机组强非线性气动特性拟合建模: 基于神经网络和多项式算法的精确快速计算方案

    纯电动汽车动力经济性仿真研究:Cruise与Simulink联合应用下的整车模型及策略解析,纯电动车辆动力经济性仿真研究:Cruise与Simulink联合仿真平台的应用,涵盖BMS、再生制动及电机驱

    纯电动汽车动力经济性仿真研究:Cruise与Simulink联合应用下的整车模型及策略解析,纯电动车辆动力经济性仿真研究:Cruise与Simulink联合仿真平台的应用,涵盖BMS、再生制动及电机驱动策略的详细解析与注释模型,Simulink整车控制器vcu应用层模型,实车在用的,支持仿真和生成 文件分类明确,每个普通功能和核心功能建有单独的库,存放在文件夹里。 有相应的表格,描述了信号的意思。 ,Simulink VCU应用层模型;实车应用;支持仿真与生成;文件分类明确;功能库分普通与核心;信号描述表格。,Simulink VCU应用层模型:实车仿真与功能库管理

    Maxwell电机与Simplorer联合仿真教程:电路搭建及矢量控制SVPWM算法实践,自定义电机模型替换指南,Maxwell电机与Simplorer联合仿真教程:电路搭建及矢量控制SVPWM算法实

    Maxwell电机与Simplorer联合仿真教程:电路搭建及矢量控制SVPWM算法实践,自定义电机模型替换指南,Maxwell电机与Simplorer联合仿真教程:电路搭建及矢量控制SVPWM算法实

    【毕业设计】基于微信平台的电子门票系统(小程序)【源码+论文+答辩ppt+开题报告+任务书】.zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。

    【毕业设计】基于微信小程序学生课程考勤系统【源码+论文+答辩ppt+开题报告+任务书】.zip

    【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。

    非常好用的工具,支持PDF,KML,KMZ,SHP,PNG,CSV的互相转换,支持最多9种转换方式

    非常好用的工具,支持PDF,KML,KMZ,SHP,PNG,CSV的互相转换,支持最多9种转换方式

Global site tag (gtag.js) - Google Analytics