diff --git a/assignments/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java b/assignments/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java index c4ffb3c18..6b02c33bd 100644 --- a/assignments/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java +++ b/assignments/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java @@ -220,21 +220,27 @@ public static SynchronizedQueueResult testQueue(QueueAdapter queue) { // initialization below to create two Java Threads, one // that's passed the producerRunnable and the other that's // passed the consumerRunnable. - Thread consumer = null; - Thread producer = null; + Thread consumer = new Thread(consumerRunnable) ; + Thread producer = new Thread(producerRunnable); // TODO - you fill in here to start the threads. More // interesting results will occur if you start the // consumer first. - + producer.start(); + consumer.start(); + // Give the Threads a chance to run before interrupting // them. Thread.sleep(100); // TODO - you fill in here to interrupt the threads. + producer.interrupt(); + consumer.interrupt(); // TODO - you fill in here to wait for the threads to // exit. + producer.join(); + consumer.join(); // Do some sanity checking to see if the Threads work as // expected. diff --git a/assignments/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java b/assignments/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java index f57064f95..3c255d505 100644 --- a/assignments/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java +++ b/assignments/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java @@ -1,5 +1,3 @@ -// Import the necessary Java synchronization and scheduling classes. - package edu.vuum.mocca; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -7,74 +5,122 @@ /** * @class SimpleAtomicLong - * + * * @brief This class implements a subset of the * java.util.concurrent.atomic.SimpleAtomicLong class using a * ReentrantReadWriteLock to illustrate how they work. */ -class SimpleAtomicLong -{ - /** - * The value that's manipulated atomically via the methods. - */ - private long mValue; - - - /** - * The ReentrantReadWriteLock used to serialize access to mValue. - */ - // TODO - add the implementation - - /** - * Creates a new SimpleAtomicLong with the given initial value. - */ - public SimpleAtomicLong(long initialValue) { - // TODO - you fill in here - } - - /** - * @brief Gets the current value - * - * @returns The current value - */ - public long get() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the updated value - */ - public long decrementAndGet() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the previous value - */ - public long getAndIncrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the previous value - */ - public long getAndDecrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the updated value - */ - public long incrementAndGet() { - // TODO - you fill in here - } -} +class SimpleAtomicLong { + /** + * The value that's manipulated atomically via the methods. + */ + private long mValue; + + /** + * The ReentrantReadWriteLock used to serialize access to mValue. + */ + + // TODO -- you fill in here by replacing the null with an + // initialization of ReentrantReadWriteLock. + private ReentrantReadWriteLock mRWLock = new ReentrantReadWriteLock(true); + + /** + * Creates a new SimpleAtomicLong with the given initial value. + */ + public SimpleAtomicLong(long initialValue) { + // TODO -- you fill in here + mValue = initialValue; + } + + /** + * @brief Gets the current value. + * + * @returns The current value + */ + + public long get() { + long value; + + // TODO -- you fill in here + mRWLock.readLock().lock(); + try { + value = mValue; + } finally { + mRWLock.readLock().unlock(); + } + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the updated value + */ + public long decrementAndGet() { + long value = 0; + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = --mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the previous value + */ + public long getAndIncrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue++; + } finally { + mRWLock.writeLock().unlock(); + } + + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the previous value + */ + public long getAndDecrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue--; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the updated value + */ + public long incrementAndGet() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = ++mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } +} diff --git a/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java b/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java index f57064f95..b88a48310 100644 --- a/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java +++ b/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java @@ -1,80 +1,125 @@ -// Import the necessary Java synchronization and scheduling classes. - package edu.vuum.mocca; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.locks.Lock; /** * @class SimpleAtomicLong - * + * * @brief This class implements a subset of the * java.util.concurrent.atomic.SimpleAtomicLong class using a * ReentrantReadWriteLock to illustrate how they work. */ -class SimpleAtomicLong -{ - /** - * The value that's manipulated atomically via the methods. - */ - private long mValue; - - - /** - * The ReentrantReadWriteLock used to serialize access to mValue. - */ - // TODO - add the implementation - - /** - * Creates a new SimpleAtomicLong with the given initial value. - */ - public SimpleAtomicLong(long initialValue) { - // TODO - you fill in here - } - - /** - * @brief Gets the current value - * - * @returns The current value - */ - public long get() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the updated value - */ - public long decrementAndGet() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the previous value - */ - public long getAndIncrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the previous value - */ - public long getAndDecrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the updated value - */ - public long incrementAndGet() { - // TODO - you fill in here - } -} +class SimpleAtomicLong { + /** + * The value that's manipulated atomically via the methods. + */ + private long mValue; + + /** + * The ReentrantReadWriteLock used to serialize access to mValue. + */ + + // TODO -- you fill in here by replacing the null with an + // initialization of ReentrantReadWriteLock. + private ReentrantReadWriteLock mRWLock = new ReentrantReadWriteLock(true); + + /** + * Creates a new SimpleAtomicLong with the given initial value. + */ + public SimpleAtomicLong(long initialValue) { + // TODO -- you fill in here + mValue = initialValue; + } + + /** + * @brief Gets the current value. + * + * @returns The current value + */ + + public long get() { + long value; + + // TODO -- you fill in here + mRWLock.readLock().lock(); + try { + value = mValue; + } finally { + mRWLock.readLock().unlock(); + } + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the updated value + */ + public long decrementAndGet() { + long value = 0; + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = --mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the previous value + */ + public long getAndIncrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue++; + } finally { + mRWLock.writeLock().unlock(); + } + + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the previous value + */ + public long getAndDecrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue--; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the updated value + */ + public long incrementAndGet() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = ++mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } +} diff --git a/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java b/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java index a867818ed..ba666a3cf 100644 --- a/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java +++ b/assignments/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java @@ -1,70 +1,100 @@ package edu.vuum.mocca; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; /** * @class SimpleSemaphore * - * @brief This class provides a simple counting semaphore - * implementation using Java a ReentrantLock and a - * ConditionObject (which is accessed via a Condition). It must - * implement both "Fair" and "NonFair" semaphore semantics, - * just liked Java Semaphores. + * @brief This class provides a simple counting semaphore implementation using + * Java a ReentrantLock and a ConditionObject. It must implement both + * "Fair" and "NonFair" semaphore semantics, just liked Java Semaphores. */ public class SimpleSemaphore { - /** - * Define a Lock to protect the critical section. - */ - // TODO - you fill in here + /** + * Define a ReentrantLock to protect the critical section. + */ + // TODO - you fill in here + ReentrantLock reentrantLock; - /** - * Define a Condition that waits while the number of permits is 0. - */ - // TODO - you fill in here + /** + * Define a ConditionObject to wait while the number of permits is 0. + */ + // TODO - you fill in here + Condition noPermitsAvailable; - /** - * Define a count of the number of available permits. - */ - // TODO - you fill in here. Make sure that this data member will - // ensure its values aren't cached by multiple Threads.. + /** + * Define a count of the number of available permits. + */ + // TODO - you fill in here. Make sure that this data member will + // ensure its values aren't cached by multiple Threads.. + int availablePermits; + int maxPermits; - public SimpleSemaphore(int permits, boolean fair) { - // TODO - you fill in here to initialize the SimpleSemaphore, - // making sure to allow both fair and non-fair Semaphore - // semantics. - } + public SimpleSemaphore(int permits, boolean fair) { + // TODO - you fill in here to initialize the SimpleSemaphore, + // making sure to allow both fair and non-fair Semaphore + // semantics. + this.maxPermits = permits; + this.availablePermits = permits; + reentrantLock = new ReentrantLock(fair); + noPermitsAvailable = reentrantLock.newCondition(); + } - /** - * Acquire one permit from the semaphore in a manner that can be - * interrupted. - */ - public void acquire() throws InterruptedException { - // TODO - you fill in here. - } + /** + * Acquire one permit from the semaphore in a manner that can be + * interrupted. + */ + public void acquire() throws InterruptedException { + // TODO - you fill in here. + reentrantLock.lockInterruptibly(); + try { + while (availablePermits == 0) { + noPermitsAvailable.await(); + } + availablePermits--; + } finally { + reentrantLock.unlock(); + } + } - /** - * Acquire one permit from the semaphore in a manner that cannot be - * interrupted. - */ - public void acquireUninterruptibly() { - // TODO - you fill in here. - } + /** + * Acquire one permit from the semaphore in a manner that cannot be + * interrupted. + */ + public void acquireUninterruptibly() { + // TODO - you fill in here. + reentrantLock.lock(); + try { + while (availablePermits == 0) { + noPermitsAvailable.awaitUninterruptibly(); + } + availablePermits--; + } finally { + reentrantLock.unlock(); + } + } - /** - * Return one permit to the semaphore. - */ - public void release() { - // TODO - you fill in here. - } + /** + * Return one permit to the semaphore. + */ + void release() { + // TODO - you fill in here. + reentrantLock.lock(); + try { + availablePermits++; + noPermitsAvailable.signal(); + } finally { + reentrantLock.unlock(); + } + } - /** - * Return the number of permits available. - */ - public int availablePermits() { - // TODO - you fill in here by changing null to the appropriate - // return value. - return null; - } + /** + * Return the number of permits available. + */ + public int availablePermits() { + // TODO - you fill in here by changing null to the appropriate + // return value. + return availablePermits; + } } diff --git a/assignments/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java b/assignments/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java index 4fd24024f..6ccede7ac 100644 --- a/assignments/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java +++ b/assignments/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java @@ -6,152 +6,158 @@ /** * @class PingPongRight * - * @brief This class implements a Java program that creates two - * instances of the PlayPingPongThread and start these thread - * instances to correctly alternate printing "Ping" and "Pong", - * respectively, on the console display. + * @brief This class implements a Java program that creates two instances of the + * PlayPingPongThread and start these thread instances to correctly + * alternate printing "Ping" and "Pong", respectively, on the console + * display. */ public class PingPongRight { - /** - * Number of iterations to run the test program. - */ - public final static int mMaxIterations = 10; - - /** - * Latch that will be decremented each time a thread exits. - */ - public static CountDownLatch mLatch = null; - - /** - * @class PlayPingPongThread - * - * @brief This class implements the ping/pong processing algorithm - * using the SimpleSemaphore to alternate printing "ping" - * and "pong" to the console display. - */ - public static class PlayPingPongThread extends Thread { - /** - * Constants to distinguish between ping and pong - * SimpleSemaphores, if you choose to use an array of - * SimpleSemaphores. If you don't use this implementation - * feel free to remove these constants. - */ - private final static int FIRST_SEMA = 0; - private final static int SECOND_SEMA = 1; - - /** - * Maximum number of loop iterations. - */ - private int mMaxLoopIterations = 0; - - /** - * String to print (either "ping!" or "pong"!) for each - * iteration. - */ - // TODO - You fill in here. - - /** - * Two SimpleSemaphores use to alternate pings and pongs. You - * can use an array of SimpleSemaphores or just define them as - * two data members. - */ - // TODO - You fill in here. - - /** - * Constructor initializes the data member(s). - */ - public PlayPingPongThread(String stringToPrint, - SimpleSemaphore semaphoreOne, - SimpleSemaphore semaphoreTwo, - int maxIterations) { - // TODO - You fill in here. - } - - /** - * Main event loop that runs in a separate thread of control - * and performs the ping/pong algorithm using the - * SimpleSemaphores. - */ - public void run() { - /** - * This method runs in a separate thread of control and - * implements the core ping/pong algorithm. - */ - - // TODO - You fill in here. - } - - /** - * Method for acquiring the appropriate SimpleSemaphore. - */ - private void acquire() { - // TODO fill in here - } - - /** - * Method for releasing the appropriate SimpleSemaphore. - */ - private void release() { - // TODO fill in here - } - } - - /** - * The method that actually runs the ping/pong program. - */ - public static void process(String startString, - String pingString, - String pongString, - String finishString, - int maxIterations) throws InterruptedException { - - // TODO initialize this by replacing null with the appropriate - // constructor call. - mLatch = null; - - // Create the ping and pong SimpleSemaphores that control - // alternation between threads. - - // TODO - You fill in here, make pingSema start out unlocked. - SimpleSemaphore pingSema = null; - // TODO - You fill in here, make pongSema start out locked. - SimpleSemaphore pongSema = null; - - System.out.println(startString); - - // Create the ping and pong threads, passing in the string to - // print and the appropriate SimpleSemaphores. - PlayPingPongThread ping = new PlayPingPongThread(/* - * TODO - You fill in - * here - */); - PlayPingPongThread pong = new PlayPingPongThread(/* - * TODO - You fill in - * here - */); - - // TODO - Initiate the ping and pong threads, which will call - // the run() hook method. - - // TODO - replace the following line with a barrier - // synchronizer call to mLatch that waits for both threads to - // finish. - throw new java.lang.InterruptedException(); - - System.out.println(finishString); - } - - /** - * The main() entry point method into PingPongRight program. - * - * @throws InterruptedException - */ - public static void main(String[] args) throws InterruptedException { - process("Ready...Set...Go!", - "Ping! ", - " Pong! ", - "Done!", - mMaxIterations); - } + /** + * Number of iterations to run the test program. + */ + public final static int mMaxIterations = 10; + + /** + * Latch that will be decremented each time a thread exits. + */ + public static CountDownLatch mLatch = null; + + /** + * @class PlayPingPongThread + * + * @brief This class implements the ping/pong processing algorithm using the + * SimpleSemaphore to alternate printing "ping" and "pong" to the + * console display. + */ + public static class PlayPingPongThread extends Thread { + /** + * Constants to distinguish between ping and pong SimpleSemaphores, if + * you choose to use an array of SimpleSemaphores. If you don't use this + * implementation feel free to remove these constants. + */ + private final static int FIRST_SEMA = 0; + private final static int SECOND_SEMA = 1; + + /** + * Maximum number of loop iterations. + */ + private int mMaxLoopIterations = 0; + + /** + * String to print (either "ping!" or "pong"!) for each iteration. + */ + private String printString; + + /** + * Two SimpleSemaphores use to alternate pings and pongs. You can use an + * array of SimpleSemaphores or just define them as two data members. + */ + SimpleSemaphore[]pingpongs = new SimpleSemaphore[2]; + + /** + * Constructor initializes the data member(s). + */ + public PlayPingPongThread(String stringToPrint, + SimpleSemaphore semaphoreOne, SimpleSemaphore semaphoreTwo, + int maxIterations) { + // TODO - You fill in here. + this.printString = stringToPrint; + this.pingpongs[FIRST_SEMA] = semaphoreOne; + this.pingpongs[SECOND_SEMA] = semaphoreTwo; + this.mMaxLoopIterations = maxIterations; + } + + /** + * Main event loop that runs in a separate thread of control and + * performs the ping/pong algorithm using the SimpleSemaphores. + */ + public void run() { + /** + * This method runs in a separate thread of control and implements + * the core ping/pong algorithm. + */ + + // TODO - You fill in here. + for (int count = 1; count <= mMaxLoopIterations; ++count) { + acquire(); + System.out.println(printString + "(" + count + ")"); + + release(); + } + mLatch.countDown(); + } + + /** + * Method for acquiring the appropriate SimpleSemaphore. + */ + private void acquire() { + pingpongs[SECOND_SEMA].acquireUninterruptibly(); + } + + /** + * Method for releasing the appropriate SimpleSemaphore. + */ + private void release() { + // TODO fill in here + pingpongs[FIRST_SEMA].release(); + } + } + + /** + * The method that actually runs the ping/pong program. + */ + public static void process(String startString, String pingString, + String pongString, String finishString, int maxIterations) + throws InterruptedException { + + // TODO initialize this by replacing null with the appropriate + // constructor call. + mLatch = new CountDownLatch(2); + + // Create the ping and pong SimpleSemaphores that control + // alternation between threads. + + // TODO - You fill in here, make pingSema start out unlocked. + SimpleSemaphore pingSema = new SimpleSemaphore(0, false); + // TODO - You fill in here, make pongSema start out locked. + SimpleSemaphore pongSema = new SimpleSemaphore(1, false); + + System.out.println(startString); + + // Create the ping and pong threads, passing in the string to + // print and the appropriate SimpleSemaphores. + PlayPingPongThread ping = new PlayPingPongThread(pingString, pingSema, + pongSema, maxIterations/* + * TODO - You fill in here + */); + PlayPingPongThread pong = new PlayPingPongThread(pongString, pongSema, + pingSema, maxIterations/* + * TODO - You fill in here + */); + + // TODO - Initiate the ping and pong threads, which will call + // the run() hook method. + ping.start(); + pong.start(); + // TODO - replace the following line with a barrier + // synchronizer call to mLatch that waits for both threads to + // finish. + try { + mLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println(finishString); + } + + /** + * The main() entry point method into PingPongRight program. + * + * @throws InterruptedException + */ + public static void main(String[] args) throws InterruptedException { + process("Ready...Set...Go!", "Ping! ", "Pong! ", "Done!", + mMaxIterations); + } } - diff --git a/assignments/week-4-assignment-3/src/edu/vuum/mocca/SimpleSemaphore.java b/assignments/week-4-assignment-3/src/edu/vuum/mocca/SimpleSemaphore.java index 5e473adf6..ba666a3cf 100644 --- a/assignments/week-4-assignment-3/src/edu/vuum/mocca/SimpleSemaphore.java +++ b/assignments/week-4-assignment-3/src/edu/vuum/mocca/SimpleSemaphore.java @@ -1,4 +1,5 @@ package edu.vuum.mocca; + import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -6,61 +7,94 @@ * @class SimpleSemaphore * * @brief This class provides a simple counting semaphore implementation using - * Java a ReentrantLock and a ConditionObject (which is accessed via a - * Condition). It must implement both "Fair" and "NonFair" semaphore - * semantics, just liked Java Semaphores. + * Java a ReentrantLock and a ConditionObject. It must implement both + * "Fair" and "NonFair" semaphore semantics, just liked Java Semaphores. */ public class SimpleSemaphore { - /** - * Define a ReentrantLock to protect the critical section. - */ - // TODO - you fill in here + /** + * Define a ReentrantLock to protect the critical section. + */ + // TODO - you fill in here + ReentrantLock reentrantLock; - /** - * Define a Condition that waits while the number of permits is 0. - */ - // TODO - you fill in here + /** + * Define a ConditionObject to wait while the number of permits is 0. + */ + // TODO - you fill in here + Condition noPermitsAvailable; - /** - * Define a count of the number of available permits. - */ - // TODO - you fill in here. Make sure that this data member will - // ensure its values aren't cached by multiple Threads.. + /** + * Define a count of the number of available permits. + */ + // TODO - you fill in here. Make sure that this data member will + // ensure its values aren't cached by multiple Threads.. + int availablePermits; + int maxPermits; - public SimpleSemaphore(int permits, boolean fair) { - // TODO - you fill in here to initialize the SimpleSemaphore, - // making sure to allow both fair and non-fair Semaphore - // semantics. - } + public SimpleSemaphore(int permits, boolean fair) { + // TODO - you fill in here to initialize the SimpleSemaphore, + // making sure to allow both fair and non-fair Semaphore + // semantics. + this.maxPermits = permits; + this.availablePermits = permits; + reentrantLock = new ReentrantLock(fair); + noPermitsAvailable = reentrantLock.newCondition(); + } - /** - * Acquire one permit from the semaphore in a manner that can be - * interrupted. - */ - public void acquire() throws InterruptedException { - // TODO - you fill in here. - } + /** + * Acquire one permit from the semaphore in a manner that can be + * interrupted. + */ + public void acquire() throws InterruptedException { + // TODO - you fill in here. + reentrantLock.lockInterruptibly(); + try { + while (availablePermits == 0) { + noPermitsAvailable.await(); + } + availablePermits--; + } finally { + reentrantLock.unlock(); + } + } - /** - * Acquire one permit from the semaphore in a manner that cannot be - * interrupted. - */ - public void acquireUninterruptibly() { - // TODO - you fill in here. - } + /** + * Acquire one permit from the semaphore in a manner that cannot be + * interrupted. + */ + public void acquireUninterruptibly() { + // TODO - you fill in here. + reentrantLock.lock(); + try { + while (availablePermits == 0) { + noPermitsAvailable.awaitUninterruptibly(); + } + availablePermits--; + } finally { + reentrantLock.unlock(); + } + } - /** - * Return one permit to the semaphore. - */ - void release() { - // TODO - you fill in here. - } + /** + * Return one permit to the semaphore. + */ + void release() { + // TODO - you fill in here. + reentrantLock.lock(); + try { + availablePermits++; + noPermitsAvailable.signal(); + } finally { + reentrantLock.unlock(); + } + } - /** - * Return the number of permits available. - */ - public int availablePermits() { - // TODO - you fill in here to return the correct result - return 0; - } + /** + * Return the number of permits available. + */ + public int availablePermits() { + // TODO - you fill in here by changing null to the appropriate + // return value. + return availablePermits; + } } diff --git a/grading-drivers/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java b/grading-drivers/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java index c4ffb3c18..6b02c33bd 100644 --- a/grading-drivers/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java +++ b/grading-drivers/week-1-assignment-0/src/edu/vuum/mooca/SynchronizedQueue.java @@ -220,21 +220,27 @@ public static SynchronizedQueueResult testQueue(QueueAdapter queue) { // initialization below to create two Java Threads, one // that's passed the producerRunnable and the other that's // passed the consumerRunnable. - Thread consumer = null; - Thread producer = null; + Thread consumer = new Thread(consumerRunnable) ; + Thread producer = new Thread(producerRunnable); // TODO - you fill in here to start the threads. More // interesting results will occur if you start the // consumer first. - + producer.start(); + consumer.start(); + // Give the Threads a chance to run before interrupting // them. Thread.sleep(100); // TODO - you fill in here to interrupt the threads. + producer.interrupt(); + consumer.interrupt(); // TODO - you fill in here to wait for the threads to // exit. + producer.join(); + consumer.join(); // Do some sanity checking to see if the Threads work as // expected. diff --git a/grading-drivers/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java b/grading-drivers/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java index f57064f95..3c255d505 100644 --- a/grading-drivers/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java +++ b/grading-drivers/week-2-assignment-1/src/edu/vuum/mocca/SimpleAtomicLong.java @@ -1,5 +1,3 @@ -// Import the necessary Java synchronization and scheduling classes. - package edu.vuum.mocca; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -7,74 +5,122 @@ /** * @class SimpleAtomicLong - * + * * @brief This class implements a subset of the * java.util.concurrent.atomic.SimpleAtomicLong class using a * ReentrantReadWriteLock to illustrate how they work. */ -class SimpleAtomicLong -{ - /** - * The value that's manipulated atomically via the methods. - */ - private long mValue; - - - /** - * The ReentrantReadWriteLock used to serialize access to mValue. - */ - // TODO - add the implementation - - /** - * Creates a new SimpleAtomicLong with the given initial value. - */ - public SimpleAtomicLong(long initialValue) { - // TODO - you fill in here - } - - /** - * @brief Gets the current value - * - * @returns The current value - */ - public long get() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the updated value - */ - public long decrementAndGet() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the previous value - */ - public long getAndIncrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the previous value - */ - public long getAndDecrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the updated value - */ - public long incrementAndGet() { - // TODO - you fill in here - } -} +class SimpleAtomicLong { + /** + * The value that's manipulated atomically via the methods. + */ + private long mValue; + + /** + * The ReentrantReadWriteLock used to serialize access to mValue. + */ + + // TODO -- you fill in here by replacing the null with an + // initialization of ReentrantReadWriteLock. + private ReentrantReadWriteLock mRWLock = new ReentrantReadWriteLock(true); + + /** + * Creates a new SimpleAtomicLong with the given initial value. + */ + public SimpleAtomicLong(long initialValue) { + // TODO -- you fill in here + mValue = initialValue; + } + + /** + * @brief Gets the current value. + * + * @returns The current value + */ + + public long get() { + long value; + + // TODO -- you fill in here + mRWLock.readLock().lock(); + try { + value = mValue; + } finally { + mRWLock.readLock().unlock(); + } + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the updated value + */ + public long decrementAndGet() { + long value = 0; + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = --mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the previous value + */ + public long getAndIncrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue++; + } finally { + mRWLock.writeLock().unlock(); + } + + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the previous value + */ + public long getAndDecrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue--; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the updated value + */ + public long incrementAndGet() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = ++mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } +} diff --git a/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java b/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java index f57064f95..b88a48310 100644 --- a/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java +++ b/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleAtomicLong.java @@ -1,80 +1,125 @@ -// Import the necessary Java synchronization and scheduling classes. - package edu.vuum.mocca; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.locks.Lock; /** * @class SimpleAtomicLong - * + * * @brief This class implements a subset of the * java.util.concurrent.atomic.SimpleAtomicLong class using a * ReentrantReadWriteLock to illustrate how they work. */ -class SimpleAtomicLong -{ - /** - * The value that's manipulated atomically via the methods. - */ - private long mValue; - - - /** - * The ReentrantReadWriteLock used to serialize access to mValue. - */ - // TODO - add the implementation - - /** - * Creates a new SimpleAtomicLong with the given initial value. - */ - public SimpleAtomicLong(long initialValue) { - // TODO - you fill in here - } - - /** - * @brief Gets the current value - * - * @returns The current value - */ - public long get() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the updated value - */ - public long decrementAndGet() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the previous value - */ - public long getAndIncrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically decrements by one the current value - * - * @returns the previous value - */ - public long getAndDecrement() { - // TODO - you fill in here - } - - /** - * @brief Atomically increments by one the current value - * - * @returns the updated value - */ - public long incrementAndGet() { - // TODO - you fill in here - } -} +class SimpleAtomicLong { + /** + * The value that's manipulated atomically via the methods. + */ + private long mValue; + + /** + * The ReentrantReadWriteLock used to serialize access to mValue. + */ + + // TODO -- you fill in here by replacing the null with an + // initialization of ReentrantReadWriteLock. + private ReentrantReadWriteLock mRWLock = new ReentrantReadWriteLock(true); + + /** + * Creates a new SimpleAtomicLong with the given initial value. + */ + public SimpleAtomicLong(long initialValue) { + // TODO -- you fill in here + mValue = initialValue; + } + + /** + * @brief Gets the current value. + * + * @returns The current value + */ + + public long get() { + long value; + + // TODO -- you fill in here + mRWLock.readLock().lock(); + try { + value = mValue; + } finally { + mRWLock.readLock().unlock(); + } + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the updated value + */ + public long decrementAndGet() { + long value = 0; + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = --mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the previous value + */ + public long getAndIncrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue++; + } finally { + mRWLock.writeLock().unlock(); + } + + return value; + } + + /** + * @brief Atomically decrements by one the current value + * + * @returns the previous value + */ + public long getAndDecrement() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = mValue--; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } + + /** + * @brief Atomically increments by one the current value + * + * @returns the updated value + */ + public long incrementAndGet() { + long value = 0; + + // TODO -- you fill in here + mRWLock.writeLock().lock(); + try { + value = ++mValue; + } finally { + mRWLock.writeLock().unlock(); + } + return value; + } +} diff --git a/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java b/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java index 581f2eb99..ba666a3cf 100644 --- a/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java +++ b/grading-drivers/week-3-assignment-2/src/edu/vuum/mocca/SimpleSemaphore.java @@ -1,8 +1,7 @@ package edu.vuum.mocca; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; /** * @class SimpleSemaphore @@ -12,58 +11,90 @@ * "Fair" and "NonFair" semaphore semantics, just liked Java Semaphores. */ public class SimpleSemaphore { - /** - * Define a ReentrantLock to protect the critical section. - */ - // TODO - you fill in here + /** + * Define a ReentrantLock to protect the critical section. + */ + // TODO - you fill in here + ReentrantLock reentrantLock; - /** - * Define a ConditionObject to wait while the number of - * permits is 0. - */ - // TODO - you fill in here + /** + * Define a ConditionObject to wait while the number of permits is 0. + */ + // TODO - you fill in here + Condition noPermitsAvailable; - /** - * Define a count of the number of available permits. - */ - // TODO - you fill in here. Make sure that this data member will - // ensure its values aren't cached by multiple Threads.. + /** + * Define a count of the number of available permits. + */ + // TODO - you fill in here. Make sure that this data member will + // ensure its values aren't cached by multiple Threads.. + int availablePermits; + int maxPermits; - public SimpleSemaphore(int permits, boolean fair) { - // TODO - you fill in here to initialize the SimpleSemaphore, - // making sure to allow both fair and non-fair Semaphore - // semantics. - } + public SimpleSemaphore(int permits, boolean fair) { + // TODO - you fill in here to initialize the SimpleSemaphore, + // making sure to allow both fair and non-fair Semaphore + // semantics. + this.maxPermits = permits; + this.availablePermits = permits; + reentrantLock = new ReentrantLock(fair); + noPermitsAvailable = reentrantLock.newCondition(); + } - /** - * Acquire one permit from the semaphore in a manner that can be - * interrupted. - */ - public void acquire() throws InterruptedException { - // TODO - you fill in here. - } + /** + * Acquire one permit from the semaphore in a manner that can be + * interrupted. + */ + public void acquire() throws InterruptedException { + // TODO - you fill in here. + reentrantLock.lockInterruptibly(); + try { + while (availablePermits == 0) { + noPermitsAvailable.await(); + } + availablePermits--; + } finally { + reentrantLock.unlock(); + } + } - /** - * Acquire one permit from the semaphore in a manner that cannot be - * interrupted. - */ - public void acquireUninterruptibly() { - // TODO - you fill in here. - } + /** + * Acquire one permit from the semaphore in a manner that cannot be + * interrupted. + */ + public void acquireUninterruptibly() { + // TODO - you fill in here. + reentrantLock.lock(); + try { + while (availablePermits == 0) { + noPermitsAvailable.awaitUninterruptibly(); + } + availablePermits--; + } finally { + reentrantLock.unlock(); + } + } - /** - * Return one permit to the semaphore. - */ - void release() { - // TODO - you fill in here. - } + /** + * Return one permit to the semaphore. + */ + void release() { + // TODO - you fill in here. + reentrantLock.lock(); + try { + availablePermits++; + noPermitsAvailable.signal(); + } finally { + reentrantLock.unlock(); + } + } - /** - * Return the number of permits available. - */ - public int availablePermits() { - // TODO - you fill in here by changing null to the appropriate - // return value. - return null; - } + /** + * Return the number of permits available. + */ + public int availablePermits() { + // TODO - you fill in here by changing null to the appropriate + // return value. + return availablePermits; + } } diff --git a/grading-drivers/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java b/grading-drivers/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java index b2845e4e2..135744450 100644 --- a/grading-drivers/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java +++ b/grading-drivers/week-4-assignment-3/src/edu/vuum/mocca/PingPongRight.java @@ -122,7 +122,7 @@ public static void process(String startString, // Create the ping and pong threads, passing in the string to // print and the appropriate SimpleSemaphores. - PlayPingPongThread ping = new PlayPingPongThread(/* + PlayPingPongThread ping = new PlayPingPongThread(finishString, pingSema, pongSema, maxIterations/* * TODO - You fill in * here */); diff --git a/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/.classpath b/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/.classpath index e6dd6025b..451fd30c0 100644 --- a/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/.classpath +++ b/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/.classpath @@ -2,7 +2,7 @@ - + diff --git a/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/src/edu/vuum/mocca/test/PingPongActivityTest.java b/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/src/edu/vuum/mocca/test/PingPongActivityTest.java index dcab37447..1107c3cd7 100644 --- a/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/src/edu/vuum/mocca/test/PingPongActivityTest.java +++ b/grading-drivers/week-5-assignment-4/W5-A4-Android-Test/src/edu/vuum/mocca/test/PingPongActivityTest.java @@ -4,7 +4,6 @@ import android.test.ActivityInstrumentationTestCase2; import android.widget.Button; import android.widget.TextView; -import android.view.WindowManager; import com.robotium.solo.Solo; @@ -54,14 +53,6 @@ public void setUp() throws Exception { outputTextView_ = (TextView) mSolo .getView(edu.vuum.mocca.R.id.pingpong_output); - // Prevent lockscreen from preventing test. - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); - } - }); - getInstrumentation().callActivityOnStart(getActivity()); getInstrumentation().callActivityOnResume(getActivity()); }