• 《面向模式的软件体系结构2用于并发和网络化对象模式》读书笔记(12) 策略化加锁


    4.2策略化加锁(Strategized Locking)

    1.问题

          运行在多线程环境中的组件必须保护其临界区不被客户机并发访问。同步机制与组件功能的集成需要解决以下两个强制条件:

          1)不同的应用程序可能要求不同的同步策略,如互斥、读写锁或信息灯。因此,应该可以按照具体应用的需求定制组件的同步机制。

          2)加入新的功能和隐错修正应很容易。特别为避免“版本混乱”应始终将这些变化一致地自动地应用于组件系列的所有成员上。

    2.解决方案

          将组件的同步特性变成“可插”的类型,用这种方式将组件的同步特性参数化。每种类型将特定的同步化策略对象化,同步策略包括互斥、读写锁、信号灯或“空”锁等。将这些可插的类型的实例定义为包含在组件中的对象,该组件可以使用这些对象有效地使其方法实现同步化。

    3.实现

    1)不考虑组件的同步特性,定义组件的接口和实现。

    2)将加锁机制策略化。许多组件有相对简单的同步特性,可以使用常用的加锁策略,如互斥和信号灯等实现这些同步特性。可以统一地使用多态性或参数化类型将同步特性策略化。一般来说,如果直到运行时才知道加锁策略,就应该使用多态性。相反,如果在编译时就知道加锁策略,那就应该使用参数化类型。参数化类型有运行效率高的特点,而多态性有运行时可扩展的潜力。

          假设使用定界加锁惯用法,策略化锁包括两个子活动:

          2.1)为加锁机制定义一个抽象接口。为了使组件能使用不同的加锁机制,这些机制的所有具体实现应该使用具有共同特征的抽象接口,用于在多态性或参数化类型的基础上获取和释放锁。

          2.2)使用定界加锁惯用法定义一个用同步特征将其策略化的哨兵类。这种设计遵循策略模式。其中,哨兵类作为拥有某一特殊锁的语境,而具体锁提供策略。

    3)更新组件的接口和实现。在策略化同步机制后,组件可以使用这些机制,通过显式地获得或释放一个锁,或者使用定义的哨兵类来保护临界区。

    4)修改组件实现以避免死锁和删除不必要的加锁开销。如果组件间存在方法调用,那么开发人员必须仔细地设计其组件实现,以避免自死锁和不必要的同步开销。

    5)定义一组具有统一接口的加锁策略,这些策略可以支持各种应用特定的并发设计。

    4.结论

    优点:

          1)增加灵活性和个性化。为特定的并发模型配置和定制一个组件是很容易的,因为组件的同步特性被策略化了。如果对于一种新的并发模型没有合适的加锁策略可用,可以在不影响已有代码的情况下扩充新的加锁策略。

          2)降低组件维护的代价。使用策略化加锁模式很容易改进组件和隐错修正,因为对于各种并发模型只有一个实现,而不是每种并发模型对应一个独立的实现。将问题集中的方法有助于减少版本混乱。

          3)改善重用性。用这种模式实现的组件不太依赖于具体的同步机制。

    不足:

          1)强行(obtrusive)加锁。

          2)过分工程化(over-engineering)。 

  • 相关阅读:
    Java的静态块与实例块(转)
    Programming Ability Test学习 1031. Hello World for U (20)
    Programming Ability Test学习 1011. World Cup Betting (20)
    Programming Ability Test学习 1027. Colors in Mars (20)
    Programming Ability Test学习 1064. Complete Binary Search Tree (30)
    Programming Ability Test学习 1008. Elevator (20)
    【maven详解-生命周期】Maven的生命周期和插件
    【maven详解-插件】maven插件学习之源码插件Source Xref
    $(document).ready(){}、$(fucntion(){})、(function(){})(jQuery)onload()的区别
    你还没真的努力过,就轻易输给了懒惰
  • 原文地址:https://www.cnblogs.com/pennant/p/2698948.html
Copyright © 2020-2023  润新知