calendar
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| calendar [2009/04/26 19:34] – franck | calendar [2009/05/14 21:04] (current) – franck | ||
|---|---|---|---|
| Line 19: | Line 19: | ||
| A simple example of a concurrent program can be found | A simple example of a concurrent program can be found | ||
| [[example|here]]. | [[example|here]]. | ||
| - | |||
| - | <code java> | ||
| - | /** | ||
| - | * An Assignment thread continuously assigns its private value to | ||
| - | * a shared value. | ||
| - | */ | ||
| - | public class Assignment extends Thread | ||
| - | { | ||
| - | /** The value shared by all Assignment objects */ | ||
| - | public static long sharedValue; | ||
| - | |||
| - | /** The private value of this Assignment object */ | ||
| - | private long privateValue; | ||
| - | |||
| - | /** | ||
| - | * Creates an Assignment object with the given private value. | ||
| - | * | ||
| - | * @param privateValue the private value of the created Assignment object. | ||
| - | */ | ||
| - | public Assignment(long privateValue) | ||
| - | { | ||
| - | this.privateValue = privateValue; | ||
| - | } | ||
| - | |||
| - | /** | ||
| - | * Continuously assigns the private value of this Assignment object | ||
| - | * to the shared value of all Assignment objects. | ||
| - | */ | ||
| - | public void run() | ||
| - | { | ||
| - | while (true) | ||
| - | { | ||
| - | Assignment.sharedValue = this.privateValue; | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <code java> | ||
| - | /** | ||
| - | * A Print thread continuously prints the value of the value shared | ||
| - | * by all Assignment objects. | ||
| - | */ | ||
| - | public class Print extends Thread | ||
| - | { | ||
| - | /** | ||
| - | * Continuously prints the value of the value shared | ||
| - | * by all Assignment objects. | ||
| - | */ | ||
| - | public void run() | ||
| - | { | ||
| - | while (true) | ||
| - | { | ||
| - | System.out.println(Assignment.sharedValue); | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <code java> | ||
| - | public class Client | ||
| - | { | ||
| - | public static void main(String[] args) | ||
| - | { | ||
| - | Assignment zero = new Assignment(0); | ||
| - | Assignment max = new Assignment(Long.MAX_VALUE); | ||
| - | Print print = new Print(); | ||
| - | zero.start(); | ||
| - | max.start(); | ||
| - | print.start(); | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| ===== March 10 ===== | ===== March 10 ===== | ||
| Line 153: | Line 80: | ||
| If you come across another source that may be useful, please email it to the instructor. | If you come across another source that may be useful, please email it to the instructor. | ||
| - | <code java> | + | A simple example |
| - | /** | + | [[printer|here]]. |
| - | | + | |
| - | * | + | |
| - | * @author Franck van Breugel | + | |
| - | */ | + | |
| - | public class Printer extends Thread | + | |
| - | { | + | |
| - | /** | + | |
| - | * Initializes this printer with the given name. | + | |
| - | * | + | |
| - | * @param name the name of this printer. | + | |
| - | * @pre. name != null | + | |
| - | */ | + | |
| - | public Printer(String name) | + | |
| - | { | + | |
| - | super(name); | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Prints the name of this printer 1000 times. | + | |
| - | */ | + | |
| - | public void run() | + | |
| - | { | + | |
| - | final int NUMBER = 1000; | + | |
| - | for (int i = 0; i < NUMBER; i++) | + | |
| - | { | + | |
| - | System.out.print(this.getName()); | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class PrinterTest | + | |
| - | { | + | |
| - | public static void main(String[] args) | + | |
| - | { | + | |
| - | new Printer(" | + | |
| - | new Printer(" | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | <code java> | + | |
| - | /** | + | |
| - | * A printer | + | |
| - | * | + | |
| - | * @author Franck van Breugel | + | |
| - | */ | + | |
| - | public class Printer implements Runnable | + | |
| - | { | + | |
| - | public void run() | + | |
| - | { | + | |
| - | final int NUMBER = 1000; | + | |
| - | for (int i = 0; i < NUMBER; i++) | + | |
| - | { | + | |
| - | System.out.print(Thread.currentThread().getName()); | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class PrinterTest | + | |
| - | { | + | |
| - | public static void main(String[] args) | + | |
| - | { | + | |
| - | Printer printer = new Printer(); | + | |
| - | new Thread(printer, | + | |
| - | new Thread(printer, | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| ===== March 31 ===== | ===== March 31 ===== | ||
| - | A solution to the readers-writers problem using semaphores | + | Implementations |
| - | First, a Reader. | + | found [[readers-writers|here]]. |
| - | <code java> | + | |
| - | package semaphore; | + | |
| - | + | ||
| - | import java.util.Random; | + | |
| - | import java.util.concurrent.Semaphore; | + | |
| - | + | ||
| - | /** | + | |
| - | * A reader. | + | |
| - | * | + | |
| - | * @author Franck van Breugel | + | |
| - | */ | + | |
| - | public class Reader extends Thread | + | |
| - | { | + | |
| - | private static int readers = 0; | + | |
| - | private static final Semaphore mutex = new Semaphore(1); | + | |
| - | + | ||
| - | /** | + | |
| - | * Initializes this reader. | + | |
| - | */ | + | |
| - | public Reader() | + | |
| - | { | + | |
| - | super(); | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Reads. | + | |
| - | */ | + | |
| - | public void run() | + | |
| - | { | + | |
| - | try | + | |
| - | { | + | |
| - | Reader.mutex.acquire(); | + | |
| - | Reader.readers++; | + | |
| - | if (Reader.readers == 1) | + | |
| - | { | + | |
| - | Writer.writer.acquire(); | + | |
| - | } | + | |
| - | Reader.mutex.release(); | + | |
| - | // read | + | |
| - | Reader.mutex.acquire(); | + | |
| - | Reader.readers--; | + | |
| - | if (Reader.readers == 0) | + | |
| - | { | + | |
| - | Writer.writer.release(); | + | |
| - | } | + | |
| - | Reader.mutex.release(); | + | |
| - | } | + | |
| - | catch (InterruptedException e) {} | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | Then, a Writer. | + | |
| - | <code java> | + | |
| - | package semaphore; | + | |
| - | + | ||
| - | import java.util.Random; | + | |
| - | import java.util.concurrent.Semaphore; | + | |
| - | + | ||
| - | /** | + | |
| - | * A writer. | + | |
| - | * | + | |
| - | * @author Franck van Breugel | + | |
| - | */ | + | |
| - | public class Writer extends Thread | + | |
| - | { | + | |
| - | public static final Semaphore writer = new Semaphore(1, | + | |
| - | + | ||
| - | /** | + | |
| - | * Initializes this writer. | + | |
| - | */ | + | |
| - | public Writer() | + | |
| - | { | + | |
| - | super(); | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Writes. | + | |
| - | */ | + | |
| - | public void run() | + | |
| - | { | + | |
| - | try | + | |
| - | { | + | |
| - | Writer.writer.acquire(); | + | |
| - | // write | + | |
| - | Writer.writer.release(); | + | |
| - | } | + | |
| - | catch (InterruptedException e) {} | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | And finally an app. | + | |
| - | <code java> | + | |
| - | package semaphore; | + | |
| - | + | ||
| - | /** | + | |
| - | * This app creates a number of readers and writers. | + | |
| - | * | + | |
| - | * @author Franck van Breugel | + | |
| - | */ | + | |
| - | public class ReadersWriters | + | |
| - | { | + | |
| - | /** | + | |
| - | * @param args[0] numbers of readers. | + | |
| - | * @param args[1] number of writers. | + | |
| - | */ | + | |
| - | public static void main(String[] args) | + | |
| - | { | + | |
| - | try | + | |
| - | { | + | |
| - | int readers = Integer.parseInt(args[0]); | + | |
| - | int writers = Integer.parseInt(args[1]); | + | |
| - | for (int i = 0; i < writers; i++) | + | |
| - | { | + | |
| - | new Writer().start(); | + | |
| - | } | + | |
| - | for (int i = 0; i < readers; i++) | + | |
| - | { | + | |
| - | new Reader().start(); | + | |
| - | } | + | |
| - | } | + | |
| - | catch (Exception e) | + | |
| - | { | + | |
| - | System.out.println(" | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Below, we present another solution to the readers-writers problem. | + | |
| - | <code java> | + | |
| - | /** | + | |
| - | * This class represents a database. | + | |
| - | * competing threads wishing to read and write. | + | |
| - | * 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 | + | |
| - | + | ||
| - | /** | + | |
| - | * Initializes this database. | + | |
| - | */ | + | |
| - | public Database() | + | |
| - | { | + | |
| - | this.readers = 0; | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Read from this database. | + | |
| - | */ | + | |
| - | public void read(int number) | + | |
| - | { | + | |
| - | synchronized(this) | + | |
| - | { | + | |
| - | this.readers++; | + | |
| - | } | + | |
| - | // read | + | |
| - | synchronized(this) | + | |
| - | { | + | |
| - | this.readers--; | + | |
| - | if (this.readers == 0) | + | |
| - | { | + | |
| - | this.notifyAll(); | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Writes to this database. | + | |
| - | */ | + | |
| - | public synchronized void write(int number) | + | |
| - | { | + | |
| - | while (this.readers != 0) | + | |
| - | { | + | |
| - | try | + | |
| - | { | + | |
| - | this.wait(); | + | |
| - | } | + | |
| - | catch (InterruptedException e) {} | + | |
| - | } | + | |
| - | // write | + | |
| - | this.notifyAll(); | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| ===== April 2 ===== | ===== April 2 ===== | ||
| Line 440: | Line 108: | ||
| [[http:// | [[http:// | ||
| - | <code java> | + | Examples of JCSP can be found [[csp|here]]. |
| - | public class Process implements CSProcess | + | |
| - | { | + | |
| - | private ChannelOutput verhoog; | + | |
| - | private ChannelOutput prolaag; | + | |
| - | + | ||
| - | public Process(ChannelOutput verhoog, ChannelOutput prolaag) | + | |
| - | { | + | |
| - | super(); | + | |
| - | this.verhoog = verhoog; | + | |
| - | this.prolaag = prolaag; | + | |
| - | } | + | |
| - | + | ||
| - | public void run() | + | |
| - | { | + | |
| - | this.prolaag.write(null); | + | |
| - | // critical section | + | |
| - | this.verhoog.write(null); | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class Semaphore implements CSProcess | + | |
| - | { | + | |
| - | private int value; | + | |
| - | private AltingChannelInput verhoog; | + | |
| - | private AltingChannelInput prolaag; | + | |
| - | + | ||
| - | public Semaphore(int value, AltingChannelInput verhoog, AltingChannelInput prolaag) | + | |
| - | { | + | |
| - | super(); | + | |
| - | this.value = value; | + | |
| - | this.verhoog = verhoog; | + | |
| - | this.prolaag = prolaag; | + | |
| - | } | + | |
| - | + | ||
| - | public void run() | + | |
| - | { | + | |
| - | final int ALTERNATIVES = 2; | + | |
| - | final int V = 0; | + | |
| - | final int P = 1; | + | |
| - | final Guard[] guard = new Guard[ALTERNATIVES]; | + | |
| - | guard[V] = this.verhoog; | + | |
| - | guard[P] = this.prolaag; | + | |
| - | final boolean[] precondition = new boolean[ALTERNATIVES]; | + | |
| - | precondition[V] = true; | + | |
| - | final Alternative alternative = new Alternative(guard); | + | |
| - | while (true) | + | |
| - | { | + | |
| - | precondition[P] = this.value > 0; | + | |
| - | switch (alternative.select(precondition)) | + | |
| - | { | + | |
| - | case V: | + | |
| - | this.verhoog.read(); | + | |
| - | this.value++; | + | |
| - | break; | + | |
| - | case P: | + | |
| - | this.prolaag.read(); | + | |
| - | this.value--; | + | |
| - | break; | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class Main | + | |
| - | { | + | |
| - | public static void main(String[] args) | + | |
| - | { | + | |
| - | Any2OneChannel verhoog = Channel.any2one(); | + | |
| - | Any2OneChannel prolaag = Channel.any2one(); | + | |
| - | Semaphore semaphore = new Semaphore(1, | + | |
| - | Process one = new Process(verhoog.out(), | + | |
| - | Process two = new Process(verhoog.out(), | + | |
| - | CSProcess[] process = { semaphore, one, two }; | + | |
| - | Parallel parallel = new Parallel(process); | + | |
| - | parallel.run(); | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| ===== April 16 ===== | ===== April 16 ===== | ||
| - | Concurrent | + | Four concurrent |
| - | + | [[stack|here]]. | |
| - | <code java> | + | |
| - | /** | + | |
| - | * A Stack. | + | |
| - | */ | + | |
| - | public interface Stack< | + | |
| - | { | + | |
| - | /** | + | |
| - | * Removes the top element from this stack and returns it. | + | |
| - | * | + | |
| - | * @return the top element of this stack. | + | |
| - | * @throw Exception if this stack is empty. | + | |
| - | */ | + | |
| - | public T pop() throws Exception; | + | |
| - | + | ||
| - | /** | + | |
| - | * Pushes the given element onto this stack. | + | |
| - | * | + | |
| - | * @param the element to be pushed onto this stack. | + | |
| - | */ | + | |
| - | public void push(T element); | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | In each implementation of the above interface we will exploit the class Node. | + | |
| - | + | ||
| - | <code java> | + | |
| - | /** | + | |
| - | * A node of a linked list. | + | |
| - | */ | + | |
| - | public class Node< | + | |
| - | { | + | |
| - | private T element; | + | |
| - | private Node< | + | |
| - | + | ||
| - | /** | + | |
| - | * Initializes this node with the given element and next node. | + | |
| - | * | + | |
| - | * @param element the element stored in the node. | + | |
| - | * @pre. element != null | + | |
| - | * @param next the next node in the list. | + | |
| - | */ | + | |
| - | public Node(T element, Node< | + | |
| - | { | + | |
| - | this.element = element; | + | |
| - | this.next = next; | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Returns the element of this node. | + | |
| - | * | + | |
| - | * @return the element of this node. | + | |
| - | */ | + | |
| - | public T getElement() | + | |
| - | { | + | |
| - | return this.element; | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Returns the next node. | + | |
| - | * | + | |
| - | * @return the next node. | + | |
| - | */ | + | |
| - | public Node< | + | |
| - | { | + | |
| - | return this.next; | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | * Sets the next node to the given node. | + | |
| - | * | + | |
| - | * @param node the new next node. | + | |
| - | */ | + | |
| - | public void setNext(Node< | + | |
| - | { | + | |
| - | this.next = next; | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | In the first implementation, | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class First< | + | |
| - | { | + | |
| - | private Node< | + | |
| - | + | ||
| - | public First() | + | |
| - | { | + | |
| - | this.top = null; | + | |
| - | } | + | |
| - | + | ||
| - | public synchronized T pop() throws Exception | + | |
| - | { | + | |
| - | if (this.top == null) | + | |
| - | { | + | |
| - | throw new Exception(); | + | |
| - | } | + | |
| - | else | + | |
| - | { | + | |
| - | T element = this.top.getElement(); | + | |
| - | this.top = this.top.getNext(); | + | |
| - | return element; | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | public synchronized void push(T element) | + | |
| - | { | + | |
| - | this.top = new Node< | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | In the second implementation, | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class Second< | + | |
| - | { | + | |
| - | private Node< | + | |
| - | + | ||
| - | public Second() | + | |
| - | { | + | |
| - | this.top = null; | + | |
| - | } | + | |
| - | + | ||
| - | public T pop() throws Exception | + | |
| - | { | + | |
| - | Node< | + | |
| - | synchronized (this.top) | + | |
| - | { | + | |
| - | if (this.top == null) | + | |
| - | { | + | |
| - | throw new Exception(); | + | |
| - | } | + | |
| - | else | + | |
| - | { | + | |
| - | node = this.top; | + | |
| - | this.top = this.top.getNext(); | + | |
| - | } | + | |
| - | } | + | |
| - | return node.getElement(); | + | |
| - | } | + | |
| - | + | ||
| - | public void push(T element) | + | |
| - | { | + | |
| - | Node< | + | |
| - | synchronized (this.top) | + | |
| - | { | + | |
| - | | + | |
| - | | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | The third implementation does not use any locking. We exploit the class AtomicReference. | + | |
| - | + | ||
| - | <code java> | + | |
| - | import java.util.concurrent.atomic.*; | + | |
| - | + | ||
| - | public class Third< | + | |
| - | { | + | |
| - | private volatile AtomicReference< | + | |
| - | + | ||
| - | public Third() | + | |
| - | { | + | |
| - | this.top = new AtomicReference< | + | |
| - | } | + | |
| - | + | ||
| - | public T pop() throws Exception | + | |
| - | { | + | |
| - | Node< | + | |
| - | do | + | |
| - | { | + | |
| - | node = this.top.get(); | + | |
| - | if (node == null) | + | |
| - | { | + | |
| - | throw new Exception(); | + | |
| - | } | + | |
| - | } | + | |
| - | while (!this.top.compareAndSet(node, | + | |
| - | return node.getElement(); | + | |
| - | } | + | |
| - | + | ||
| - | public void push(T element) | + | |
| - | { | + | |
| - | Node< | + | |
| - | do | + | |
| - | { | + | |
| - | node.setNext(this.top.get()); | + | |
| - | } | + | |
| - | while (!this.top.compareAndSet(node.getNext(), | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Also the fourth implementation does not use any locking. This time we exploit the class AtomicReferenceFieldUpdater. | + | |
| - | + | ||
| - | <code java> | + | |
| - | import java.util.concurrent.atomic.*; | + | |
| - | + | ||
| - | public class Fourth< | + | |
| - | { | + | |
| - | private volatile Node< | + | |
| - | + | ||
| - | private static final AtomicReferenceFieldUpdater< | + | |
| - | = AtomicReferenceFieldUpdater.newUpdater(Fourth.class, | + | |
| - | + | ||
| - | public Fourth() | + | |
| - | { | + | |
| - | this.top = null; | + | |
| - | } | + | |
| - | + | ||
| - | public T pop() throws Exception | + | |
| - | { | + | |
| - | Node< | + | |
| - | do | + | |
| - | { | + | |
| - | node = this.top; | + | |
| - | if (node == null) | + | |
| - | { | + | |
| - | throw new Exception(); | + | |
| - | } | + | |
| - | } | + | |
| - | while (Fourth.topUpdater.compareAndSet(this, | + | |
| - | return node.getElement(); | + | |
| - | } | + | |
| - | + | ||
| - | public void push(T element) | + | |
| - | { | + | |
| - | Node node = new Node< | + | |
| - | do | + | |
| - | { | + | |
| - | node.setNext(this.top); | + | |
| - | } | + | |
| - | while (Fourth.topUpdater.compareAndSet(this, | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| ===== April 21 ===== | ===== April 21 ===== | ||
| Line 797: | Line 144: | ||
| Willem Visser, Klaus Havelund, Guillaume Brat, SeungJoon Park and Flavio Lerda. [[http:// | Willem Visser, Klaus Havelund, Guillaume Brat, SeungJoon Park and Flavio Lerda. [[http:// | ||
| - | More information about Java PathFinder can be found | + | |
| - | [[jpf: | + | |
| ===== May 7 ===== | ===== May 7 ===== | ||
| + | |||
| + | More information about Java PathFinder can be found | ||
| + | [[jpf: | ||
| ===== May 12 ===== | ===== May 12 ===== | ||
| + | |||
| + | Information about handling native code with Java PathFinder can be found | ||
| + | [[jpf-native: | ||
| ===== May 14 ===== | ===== May 14 ===== | ||
calendar.1240774471.txt.gz · Last modified: by franck
