2011-11-14 41 views
1

我使用JBossCache的“马拉格塔” 3.2.0.GAJBoss缓存。并发问题

我在生产环境中面临着奇怪的问题,有时写到JBoss缓存不能正常工作。我试图重现这种情况与简单的Java应用程序

public static void testCache() { 
    Cache cache = new DefaultCacheFactory().createCache(false); 
    cache.create(); 
    cache.start(); 
    final Node node = cache.getRoot().addChild(Fqn.fromString("/child1")); 
    int threadsCount = 20; 
    final CyclicBarrier b = new CyclicBarrier(threadsCount); 
    for (int i = 0; i < threadsCount; i++) { 
     final long j = i; 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        b.await(); 
        String name = RandomGenerator.getRandomName(4); 
        node.put(j, name); 
        String nameFromCache = (String) node.get(j); 
        if (!name.equals(nameFromCache)) { 
         System.out.println("error"); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 
} 

不时,本次测试输出“错误”,这是我从static void main运行失败。 3次运行中的1次返回“错误”消息。它只是返回null。我无法在每台机器上重现它。

任何线索?

+0

在访问它之前可能需要锁定节点吗? – Fakrudeen

回答

2

你的代码看起来很好,所以它可能是Jboss缓存是异步的。 Javadocs中没有任何内容能够保证缓存何时更新。

我知道在很多分布式缓存实现中,put操作被写出来,甚至缓存的本地实例也从入站消息更新,而不是直接通过本地调用。这允许缓存正确地序列化其更新,以便在网络中的所有节点上以正确的顺序处理来自多台机器的更新。

要做的一件事就是将缓存设置为LOCAL。类似以下内容:

Configuration config = new Configuration(); 
config.setCacheMode(LOCAL); 
Cache cache = new DefaultCacheFactory().createCache(config, false); 
... 

如果这样做没有失败,那么我怀疑我是正确的。即使它仍然失败,我可能是正确的,因为LOCAL模式可能仍然有一个环回网络堆栈或其他东西。

希望这会有所帮助。

+0

默认情况下,缓存在本地模式下运行,似乎它是jboss缓存错误。 – user12384512

+0

要尝试的另一件事是将旋转循环放入每个线程中,并查看空响应消失需要多长时间。 – Gray