/* * (c) Copyright 2009 Hewlett-Packard Development Company, LP * All rights reserved. * [See end of file] */ package jenaplus; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.openjena.atlas.logging.Log; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.LockMRSW; public class TestMRSW { static { Log.setLog4j() ; } static Lock lock = new LockMRSW() ; static AtomicInteger readerCount = new AtomicInteger(0) ; static AtomicInteger writerCount = new AtomicInteger(0) ; public static void main(String... args) throws Exception { //Log.enable(LockMRSW.class) ; int wThreads = 3 ; int rThreads = 5 ; List threads = new ArrayList(); for ( int i = 0 ; i < rThreads ; i++ ) threads.add(new Thread(new ReaderRunner())) ; for ( int i = 0 ; i < wThreads ; i++ ) threads.add(new Thread(new WriterRunner())) ; for (Thread thread: threads) thread.start(); for (Thread thread: threads) thread.join(); } static void check() { // Not perfect when called from outside the critical region. // Can see r = 1, then [threads run, r -> 0, w -> 1] read w = 1 => check fails. int r = readerCount.intValue() ; int w = writerCount.intValue() ; if ( r > 0 && w > 0 ) System.err.printf("r=%d w=%d", r, w) ; if ( r == 0 && w > 1 ) System.err.printf("r=%d w=%d", r, w) ; if ( r < 0 || w < 0 ) System.err.printf("r=%d w=%d", r, w) ; } static class ReaderRunner implements Runnable { @Override public void run() { while(true) { //Checks here may see inconsistency. randomWait(5) ; try { lock.enterCriticalSection(Lock.READ) ; readerCount.incrementAndGet() ; check() ; randomWait(10) ; check() ; } finally { readerCount.decrementAndGet() ; lock.leaveCriticalSection() ; } } } } static class WriterRunner implements Runnable { @Override public void run() { while(true) { //Bad - check() ; randomWait(5) ; try { lock.enterCriticalSection(Lock.WRITE) ; writerCount.incrementAndGet() ; check() ; randomWait(10) ; check() ; } finally { writerCount.decrementAndGet() ; lock.leaveCriticalSection() ; } } } } static Random random = new Random() ; static int randomWait(int milliseconds) { return random.nextInt(milliseconds) ; } } /* * (c) Copyright 2009 Hewlett-Packard Development Company, LP * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */