* @throws Exception
*/
public void runContentionTest(final int pages, final int workers, final Duration duration)
throws Exception
{
final PageAccessSynchronizer sync = new PageAccessSynchronizer(Duration.seconds(1));
final AtomicInteger[] counts = new AtomicInteger[pages];
for (int i = 0; i < counts.length; i++)
{
counts[i] = new AtomicInteger();
}
final AtomicInteger hits = new AtomicInteger();
final String[] error = new String[1];
class Worker extends Thread
{
@Override
public void run()
{
Random random = new Random();
Time start = Time.now();
while (start.elapsedSince().lessThan(duration) && error[0] == null)
{
logger.info("{} elapsed: {}, duration: {}", new Object[] {
Thread.currentThread().getName(), start.elapsedSince(), duration });
int page1 = random.nextInt(counts.length);
int page2 = random.nextInt(counts.length);
int count = 0;
while (page2 == page1 && count < 100)
{
page2 = random.nextInt(counts.length);
count++;
}
if (page2 == page1)
{
throw new RuntimeException("orly?");
}
try
{
sync.lockPage(page1);
sync.lockPage(page2);
// have locks, increment the count
counts[page1].incrementAndGet();
counts[page2].incrementAndGet();
hits.incrementAndGet();
// hold the lock for some time
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
error[0] = "Worker :" + Thread.currentThread().getName() +
" interrupted";
}
// decrement the counts
counts[page1].decrementAndGet();
counts[page2].decrementAndGet();
// release lock
}
catch (CouldNotLockPageException e)
{
// ignore
}
finally
{
sync.unlockAllPages();
}
}
}
}