所以可以说我有一个 大小的服务器阵列设置如下:

替代文本 http://www.terracotta.org/web/download/attachments/43909161/ServerArrayMirrorGroup.png

我有一个简单的 JavaBean/POJO:

package example;

public class Person {
  private OtherObject obj;

  public void setObj(OtherObject theObj) {
    synchronized (this) {
      obj = theObj;
    }
  }

  public OtherObject getObj() {
    synchronized (this) {
      return obj;
    }
  }
}

现在,如果其中一个客户端对 TC 根(数据结构)中的 Person 对象调用 Person.setObj(OtherObject),则 同步块 (在 Person.setObj(OtherObject) 中)在该客户端上持有:

1) 直到全部 服务器的数量 大小的服务器数组是否已与 Person.obj 属性同步/更新?

或者

2) 直到“活动”服务器与更新的 Person.obj 属性同步?然后另一个(N-1)阵列中的服务器是否尽可能同步?

或者

3)我忽略的其他方法?

有帮助吗?

解决方案

答案实际上并不是 1 或 2。对象在服务器镜像组中条带化。第一次设置此字段时,将创建一个事务,并且为第一个事务选择的镜像组将“拥有”该对象。

对于 1 和 2,并非所有活动服务器组都需要更新,因此无需等待其中任何一个条件。

您可以在 Terracotta 文档中找到有关配置 Terracotta 服务器阵列的更多信息:

从锁定的角度来看,在执行对象修改时,将保持此 Person 对象上的集群锁(跨集群的互斥)。同步块的范围形成了上面提到的事务。在 getObj() 方法中,您可以将其配置为读锁,这将允许集群中的多个并发读取器。

其他提示

假设其他人都有对您的对象的引用,并且可以在您这样做时/之前/之后触摸它。因此解决方案是添加锁,并且

  • 获取锁
  • 修改对象
  • 释放锁

这正是 同步的 做...它创建一个队列并且 同步方法 不能被多次调用...但如果底层对象在某处被引用,则可能会被触及。

看:

我不熟悉他们的(Terracotta)实现,但从JMM的角度来看,它应该采用群集范围的锁定。但是,这个例子非常简单;只是更改引用,这可能会导致它转换为更像是易失性写入的内容,并完全避免锁定。

但是,如果你在同步块中做了非平凡的事情,那么我会假设TC在同步块的开始处悲观地采取了一个cluser-wide锁。如果他们没有,他们将与JMM规格不一致。据我所知。

换句话说,您的选项#1。所以,要小心你在集群中共享的东西,并且尽可能使用不可变对象和java.util.concurrent。*数据结构 - 后者在TC中获得特殊的内在爱。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top