package org.multiverse.stms.gamma.integration.blocking; import org.junit.Before; import org.junit.Test; import org.multiverse.TestThread; import org.multiverse.TestUtils; import org.multiverse.api.Txn; import org.multiverse.api.callables.TxnVoidCallable; import org.multiverse.api.references.TxnLong; import static org.multiverse.TestUtils.joinAll; import static org.multiverse.TestUtils.startAll; import static org.multiverse.api.StmUtils.*; import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn; public class ManyListenersStressTest { private int refCount = 10; private int threadCount = 5; private volatile boolean stop; private TxnLong[] refs; private StressThread[] threads; @Before public void setUp() { clearThreadLocalTxn(); stop = false; threads = new StressThread[threadCount]; for (int k = 0; k < threadCount; k++) { threads[k] = new StressThread(k + 1, k == threadCount - 1 ? 1 : k + 2); } refs = new TxnLong[refCount]; for (int k = 0; k < refCount; k++) { refs[k] = newTxnLong(0); } } @Test public void test() { refs[0].atomicSet(1); startAll(threads); TestUtils.sleepMs(30000); stop = true; refs[0].atomicSet(-1); joinAll(threads); } class StressThread extends TestThread { private int wakeup; long count; private int signal; public StressThread(int wakeup, int signal) { super("StressThread-" + wakeup); this.wakeup = wakeup; this.signal = signal; } @Override public void doRun() throws Exception { while (!stop) { atomic(new TxnVoidCallable() { @Override public void call(Txn tx) throws Exception { for (TxnLong ref : refs) { final long value = ref.get(); if (value == -1) { return; } if (value == wakeup) { ref.set(0); refs[TestUtils.randomInt(refs.length)].set(signal); return; } } retry(); } }); count++; if (count % 10000 == 0) { System.out.printf("%s is at %s\n", getName(), count); } } } } }