【问题标题】:Client-side locking客户端锁定
【发布时间】:2015-09-18 11:40:46
【问题描述】:

以下是JCIP的摘录

作者说,为了使上面的代码线程安全,我们必须使用客户端锁定。

为了使这种方法有效,我们必须使用与 List 相同的锁,即使用客户端锁定或外部锁定。客户端锁定需要保护使用某个对象 X 的客户端代码以及 X 用来保护其自身状态的锁。为了使用客户端锁定,您必须知道 X 使用什么锁。

为什么我们不能一开始就简单地将 List 对象设为私有以使 ListHelper 类线程安全?

【问题讨论】:

  • 好点,这就是为什么你应该封装对内部状态的访问,特别是当它应该是线程安全的时候。尽管您仍然可以通过反射和其他东西访问它,但这是一个不同的主题。

标签: java multithreading


【解决方案1】:

ListHelper 的每个实例都包含自己的列表的情况下,您可以将该列表设为私有并仅在ListHelper 实例上同步。我想这是一个有点构建的例子,用尽可能少的代码来说明一点。 IMO 名称 ListHelper 意味着我可以传递一个外部列表,该列表显然可以被多个 ListHelper 实例重用。

我想说的重点是:在不改变 list 的可见性(可能会破坏其他代码)的情况下,与当前的 ListHelper 实例相比,您最好在 list 上同步。

【讨论】:

    【解决方案2】:

    这里的重点是表明,如果你使用同步列表,并且你想添加另一个线程安全的方法,你必须使用相同的锁。此处的目的是表明,如果您在辅助类中对此进行同步,但依赖于列表提供的同步上的其他方法(锁定列表实例 - 它将破坏线程安全。

    【讨论】:

      【解决方案3】:

      是的,我们可以简单地将 List 对象设为私有,以使 ListHelper 类线程安全。这样,List 对象就不需要是线程安全的了。

      class ImprovedList<T> {
          private final List<T> list;
      
          public ImprovedList(List<T> list) {
              this.list = list;
          }
      
          public synchronized boolean putIfAbsent(T x) {
              boolean absent = !list.contains(x);
              if (absent)
                  list.add(x);
              return absent;
          }
      }
      

      【讨论】:

        【解决方案4】:

        如果我们将列表设为私有,那么除了 put-if-absent 之外,您将如何利用列表的其他操作?然后您还必须实现列表的所有其他操作,因此要实现所有列表操作,您将使用 List 实现 ListHelper。现在,您正默默地走向作曲模式。 由于您使用 List 接口实现了 ListHelper,所以现在它不再是 Helper 类,它本身变成了列表,因此我们可以说它是一个 ImprovedList

        class ImprovedList<T> {
            private final List<T> list;
        
            public ImprovedList(List<T> list) {
                this.list = list;
            }
        
            public synchronized boolean putIfAbsent(T x) {
                boolean absent = !list.contains(x);
                if (absent)
                    list.add(x);
                return absent;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-02-01
          • 1970-01-01
          • 2018-09-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-03
          • 2020-10-20
          • 1970-01-01
          相关资源
          最近更新 更多