EhCache addCacheIfAbsent

在项目用到 EhCache  来cache 从数据库中query 出来的reference 数据。 按理说ehcahce 非常成熟了但是在用的它的addCacheIfAbsent  api 时, 居然碰到它不是线程安全的。 从它api 字面上来说绝对不应该是线程不安全的, 放狗一搜果然是个bug。 这么低级的bug 还是在最新的版本2.7.0 才fix。  但是我们项目只用到它的ehcache-core.jar 不想用太多它的特性, 下了个 ehcache-core.2.6.9.jar 来看看 release 日期是 2041-4-8  但愿没有问题哈。  

在它的网站上找的bug 的链接 https://jira.terracotta.org/jira/browse/EHC-970, 其中有段测试代码。 其中的代码居然有问题, 所以就改下 放到这个地方看看有没有大家需要的。 

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;

import org.junit.Test;

  
public class EhcacheTest {  
  
    private static final String CACHE_NAME = "test-cache";  
    private  CacheManager cm ; //= CacheManager.getInstance();  
    private final AtomicLong counter = new AtomicLong(0L);
     
	private int		maxEntriesLocalHeap	= 20000;

	private long	maxBytesLocalHeap	= 1024 * 1024 * 100;

	private boolean	isExpiryTimeFixed	= true;

	private int		timeToIdleSeconds	= 30 * 1000;

	private int		timeToLiveSeconds	= 30 * 1000;

	private boolean	overflowToOffHeap	= false;

	private boolean	eternal				= false;


	public Configuration getEhcacheConfig() {
		
		CacheConfiguration dcc = new CacheConfiguration();
		dcc.setMaxEntriesLocalHeap(maxEntriesLocalHeap);
		if (maxEntriesLocalHeap == 0) {
			dcc.setMaxBytesLocalHeap(maxBytesLocalHeap);
		}
		dcc.setTimeToIdleSeconds(timeToIdleSeconds);
		dcc.setTimeToLiveSeconds(timeToLiveSeconds);
		dcc.setOverflowToOffHeap(overflowToOffHeap);
		dcc.setEternal(eternal);

		Configuration configuration = new Configuration();
		configuration.setDefaultCacheConfiguration(dcc);
		
		configuration.setUpdateCheck(false);//application instant can not connect web site

		return configuration;
	}
    
    @Test  
    public void test_10000_Executions() throws InterruptedException {  
        final Executor executor = Executors.newFixedThreadPool(10);
        
    	cm = CacheManager.create(getEhcacheConfig());
        
        for (int i = 0; i < 100000; i++) {  
            executor.execute(new CreateAndRemoveCache());  
            if ((i%1000) == 0) {  
                  
            }  
                  
              
        }  
        
        while(counter.get() < 100000) {
           Thread.sleep(1000L);
           System.out.println("i=" + counter.get());
        }  
    }  
  
    public class CreateAndRemoveCache implements Runnable {  
  
        public CreateAndRemoveCache() {  
        }  
  
        @Override  
        public void run() {  
              
            cm.addCacheIfAbsent(CACHE_NAME);  
            cm.removeCache(CACHE_NAME);  
            counter.addAndGet(1);
        }  
    }  
}  

这段代码在 2.5.1 下会抛出 Item 已经存在的exception , 在 2.6.9 就不会。  好吧, 就暂时升级jar 来fix 这个问题把。

猜你喜欢

转载自bruce008.iteye.com/blog/2105334