====== Java PathFinder ====== A lot of information about JPF can be found [[http://javapathfinder.sourceforge.net/|here]]. More information can be found [[http://www.cse.yorku.ca/~sergey/jpf/|here]]. Although it describes an old version of JPF, [[http://www.havelund.com/Publications/jpf-manual.ps|this]] manual may be useful. To configure JPF, you may want to use a jpf.properties file containing search.class = gov.nasa.jpf.search.heuristic.HeuristicSearch search.heuristic.class = gov.nasa.jpf.search.heuristic.BFSHeuristic to use a breadth-first traversal of the state space (rather than a depth-first traversal which is the default). To check for race conditions, you may want to add\\ jpf.listener = gov.nasa.jpf.tools.precise.PreciseRaceDetector to your jpf.properties file. To check some properties of our solution to the readers-writers problem by means of JPF, we modified our solution as follows (the attribute writers and assertions have been added). /** * This class represents a database. There are many competing * threads wishing to read and write. It is acceptable to have * multiple processes reading at the same time, but if one thread * is writing then no other process may either read or write. */ public class Database { private int readers; // number of active readers private int writers; // number of active writers /** Initializes this database. */ public Database() { this.readers = 0; } /** Read from this database. @param number Number of the reader. */ public void read(int number) { synchronized(this) { this.readers++; System.out.println("Reader " + number + " starts reading."); } final int DELAY = 5000; try { Thread.sleep((int) (Math.random() * DELAY)); } catch (InterruptedException e) {} assert((this.writers == 1 && this.readers == 0) || this.writers == 0); synchronized(this) { System.out.println("Reader " + number + " stops reading."); this.readers--; if (this.readers == 0) { this.notifyAll(); } } } /** Writes to this database. @param number Number of the writer. */ public synchronized void write(int number) { while (this.readers != 0) { try { this.wait(); } catch (InterruptedException e) {} } System.out.println("Writer " + number + " starts writing."); this.writers++; final int DELAY = 5000; try { Thread.sleep((int) (Math.random() * DELAY)); } catch (InterruptedException e) {} assert((this.writers == 1 && this.readers == 0) || this.writers == 0); this.writers--; System.out.println("Writer " + number + " stops writing."); this.notifyAll(); } }