兵马俑是如何在这种情况下工作的?

时间:2009-05-02 17:24:57

标签: java failover high-availability terracotta

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

alt text 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),那么 synchronized块(在Person.setObj(OtherObject)中)是客户持有:

1)在使用该Person.obj属性同步/更新 N 大小的服务器阵列中的所有 N 服务器之前?

2)直到“活动”服务器与更新后的Person.obj属性同步?那么阵列中的其他( N-1 )服务器会尽可能同步吗?

3)我正在寻找其他一些方法吗?

3 个答案:

答案 0 :(得分:5)

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

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

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

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

答案 1 :(得分:3)

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

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

这正是 synchronized 所做的......它创建了一个队列而 synchronized方法不能被多次调用......但底层对象可能会如果在某个地方被引用,请被触及。

请参阅:

答案 2 :(得分:0)

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

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

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