/* * Copyright (C) 2010 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ import junit.framework.TestCase; import org.infinispan.Cache; import org.infinispan.config.Configuration; import org.infinispan.manager.DefaultCacheManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; public class TestCacheSize extends TestCase { public void testMultiThreading() throws Exception { long time = System.currentTimeMillis(); Configuration config = new Configuration(); config.setExpirationMaxIdle(0); final Cache cache = (new DefaultCacheManager(config)).getCache(); final int totalElement = 100; final int totalTimes = 20; int reader = 20; int writer = 10; int remover = 5; int cleaner = 1; final CountDownLatch startSignalWriter = new CountDownLatch(1); final CountDownLatch startSignalOthers = new CountDownLatch(1); final CountDownLatch doneSignal = new CountDownLatch(reader + writer + remover); final List errors = Collections.synchronizedList(new ArrayList()); for (int i = 0; i < writer; i++) { final int index = i; Thread thread = new Thread() { public void run() { try { startSignalWriter.await(); for (int j = 0; j < totalTimes; j++) { for (int i = 0; i < totalElement; i++) { cache.put("key" + i, "value" + i); } if (index == 0 && j == 0) { // The cache is full, we can launch the others startSignalOthers.countDown(); } sleep(50); } } catch (Exception e) { errors.add(e); } finally { doneSignal.countDown(); } } }; thread.start(); } startSignalWriter.countDown(); for (int i = 0; i < reader; i++) { Thread thread = new Thread() { public void run() { try { startSignalOthers.await(); for (int j = 0; j < totalTimes; j++) { for (int i = 0; i < totalElement; i++) { cache.get("key" + i); } sleep(50); } } catch (Exception e) { errors.add(e); } finally { doneSignal.countDown(); } } }; thread.start(); } for (int i = 0; i < remover; i++) { Thread thread = new Thread() { public void run() { try { startSignalOthers.await(); for (int j = 0; j < totalTimes; j++) { for (int i = 0; i < totalElement; i++) { cache.remove("key" + i); } sleep(50); } } catch (Exception e) { errors.add(e); } finally { doneSignal.countDown(); } } }; thread.start(); } doneSignal.await(); for (int i = 0; i < totalElement; i++) { cache.put("key" + i, "value" + i); } assertEquals(totalElement, cache.size()); final CountDownLatch startSignal = new CountDownLatch(1); final CountDownLatch doneSignal2 = new CountDownLatch(writer + cleaner); for (int i = 0; i < writer; i++) { Thread thread = new Thread() { public void run() { try { startSignal.await(); for (int j = 0; j < totalTimes; j++) { for (int i = 0; i < totalElement; i++) { cache.put("key" + i, "value" + i); } sleep(50); } } catch (Exception e) { errors.add(e); } finally { doneSignal2.countDown(); } } }; thread.start(); } for (int i = 0; i < cleaner; i++) { Thread thread = new Thread() { public void run() { try { startSignal.await(); for (int j = 0; j < totalTimes; j++) { sleep(150); cache.clear(); } } catch (Exception e) { errors.add(e); } finally { doneSignal2.countDown(); } } }; thread.start(); } cache.clear(); assertEquals(0, cache.size()); if (!errors.isEmpty()) { for (Exception e : errors) { e.printStackTrace(); } throw errors.get(0); } System.out.println("Total Time = " + (System.currentTimeMillis() - time)); } }