Contents
- .
- ./BoundedBuffer.java
- ./CriticalSectionEx.java
- ./index.html
- ./SerializationExCond.java
- ./SerializationEx.java
- ./SerializationExSem.java
- ./SodaMachineWithConditionVariable.java
- ./SodaMachineWithSemaphore.java
. 1/9
[top][prev][next]
./BoundedBuffer.java 2/9
[top][prev][next]
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
/**
* Adapted from https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html
*
* @author CSCI330
*/
class BoundedBuffer {
final Lock lock = new ReentrantLock();
/** the buffer is not full.
Consumer signals when it has taken something from the buffer,
so the buffer is not full. */
final Condition notFull = lock.newCondition();
/** the buffer is not empty.
Producer signals when it has put something in the buffer, so the buffer is not empty. */
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
private int putptr, takeptr, count;
public static void main(String args[]) {
BoundedBuffer bbuf = new BoundedBuffer();
Thread producer = new Producer(bbuf);
Thread consumer = new Consumer(bbuf);
producer.start();
consumer.start();
}
/**
* If the buffer is full, can't put any items.
*/
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) // wrap pointer around
putptr = 0;
count++;
notEmpty.signal();
} finally {
lock.unlock();
}
}
/**
* If take is attempted on an empty buffer, wait
*/
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) // wrap pointer around
takeptr = 0;
count--;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
class Producer extends Thread {
private BoundedBuffer bb;
public Producer( BoundedBuffer bb ) {
this.bb = bb;
}
public void run() {
Integer num = 0;
while( true ) {
try {
bb.put(num);
} catch(InterruptedException exc ) {
exc.printStackTrace();
}
num ++;
if( num == 10 ) {
yield();
num = 0;
}
}
}
}
class Consumer extends Thread {
private BoundedBuffer bb;
public Consumer( BoundedBuffer bb ) {
this.bb = bb;
}
public void run() {
Object o = null;
while( true ) {
try {
o = bb.take();
} catch(InterruptedException exc ) {
exc.printStackTrace();
}
System.out.println("read: " + o);
}
}
}
./CriticalSectionEx.java 3/9
[top][prev][next]
/**
* A motivating example for thread synchronization -- mutual exclusion problem.
*
* Periodically prints x[0], while two threads are increasing or decreasing,
* respectively, its value.
*
* @author Grant Braught
*
*/
public class CriticalSectionEx {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
Integer[] x = { new Integer(0) };
Thread threadInc = new IncThread(x);
Thread threadDec = new DecThread(x);
threadInc.start();
threadDec.start();
try {
threadInc.join();
threadDec.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(x[0] + "\t");
if (i % 10 == 0) {
System.out.println();
}
}
}
}
/*
* Increases x[0] by 1, 500,000
*/
class IncThread extends Thread {
private Integer[] x;
public IncThread(Integer[] x) {
this.x = x;
}
public void run() {
for (int i = 0; i < 500000; i++) {
x[0] = new Integer(x[0] + 1);
}
}
}
/*
* Decreases x[0] by 1, 500,000 times
*/
class DecThread extends Thread {
private Integer[] x;
public DecThread(Integer[] x) {
this.x = x;
}
public void run() {
for (int i = 0; i < 500000; i++) {
x[0] = new Integer(x[0] - 1);
}
}
}
./index.html 4/9
[top][prev][next]
<html>
<head><title>Examples for /home/faculty/sprenkle/public_html/cs330/examples/23-java_synchronization</title>
<link rel="stylesheet" type="text/css" href="http://www.cs.wlu.edu/~sprenkle/cs330/css/themes/spacelab.min.css" />
<link rel="stylesheet" type="text/css" href="http://www.cs.wlu.edu/~sprenkle/cs330/css/course.css" />
<link rel="stylesheet" type="text/css" href="http://www.cs.wlu.edu/~sprenkle/cs330/css/syntax.css" />
<link rel="stylesheet" type="text/css" href="http://www.cs.wlu.edu/~sprenkle/cs330/css/style.css" />
</head>
<body>
<h1>Examples for /home/faculty/sprenkle/public_html/cs330/examples/23-java_synchronization</h1>
<ul>
<li><a href=".//code.html">All IN ONE FILE (pretty syntax)</a>
<li><a href=".//BoundedBuffer.java">BoundedBuffer.java</a></li>
<li><a href=".//CriticalSectionEx.java">CriticalSectionEx.java</a></li>
<li><a href=".//SerializationEx.java">SerializationEx.java</a></li>
<li><a href=".//SerializationExCond.java">SerializationExCond.java</a></li>
<li><a href=".//SerializationExSem.java">SerializationExSem.java</a></li>
<li><a href=".//SodaMachineWithConditionVariable.java">SodaMachineWithConditionVariable.java</a></li>
<li><a href=".//SodaMachineWithSemaphore.java">SodaMachineWithSemaphore.java</a></li>
</ul>
</body>
./SerializationExCond.java 5/9
[top][prev][next]
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* A solution using condition variables
*
* @author Grant Braught
* @author CSCI330
*/
public class SerializationExCond {
public static Lock myLock = new ReentrantLock();
public static Condition notDone = myLock.newCondition();
public static boolean done;
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
int[] x = { 1, 0 };
Thread threadA = new ThreadACond(x);
Thread threadB = new ThreadBCond(x);
done = false;
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
}
if (i % 10 == 0) {
System.out.println();
} else {
System.out.print("\t");
}
}
}
}
class ThreadACond extends Thread {
private int[] x;
public ThreadACond(int[] x) {
this.x = x;
}
public void run() {
doWork();
SerializationExCond.myLock.lock();
x[0] = 5;
doWork();
System.out.print(x[0] + " ");
SerializationExCond.done = true;
SerializationExCond.notDone.signal();
SerializationExCond.myLock.unlock();
}
public void doWork() {
for (int i = 0; i < 100000; i++) {
new Double(Math.random());
}
}
}
class ThreadBCond extends Thread {
private int[] x;
public ThreadBCond(int[] x) {
this.x = x;
}
public void run() {
doWork();
SerializationExCond.myLock.lock();
while (!SerializationExCond.done) {
try {
SerializationExCond.notDone.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
x[1] = x[0] + 3;
doWork();
System.out.print(x[1] + " ");
SerializationExCond.myLock.unlock();
}
public void doWork() {
for (int i = 0; i < 100000; i++) {
new Double(Math.random());
}
}
}
./SerializationEx.java 6/9
[top][prev][next]
/**
* A motivating example for thread serialization
* -- want the threads to alternate --
* not execute at the same time.
*
* @author Grant Braught
*/
public class SerializationEx {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
int[] x = { 1, 0 };
Thread ta = new ThreadA(x);
Thread tb = new ThreadB(x);
ta.start();
tb.start();
try {
ta.join();
tb.join();
} catch (InterruptedException e) {
}
if (i % 10 == 0) {
System.out.println();
} else {
System.out.print("\t");
}
}
}
}
class ThreadA extends Thread {
private int[] x;
public ThreadA(int[] x) {
this.x = x;
}
public void run() {
doWork();
x[0] = 5;
doWork();
System.out.print(x[0] + " ");
}
public void doWork() {
for (int i = 0; i < 100000; i++) {
new Double(Math.random());
}
}
}
class ThreadB extends Thread {
private int[] x;
public ThreadB(int[] x) {
this.x = x;
}
public void run() {
doWork();
x[1] = x[0] + 3;
doWork();
System.out.print(x[1] + " ");
}
public void doWork() {
for (int i = 0; i < 100000; i++) {
new Double(Math.random());
}
}
}
./SerializationExSem.java 7/9
[top][prev][next]
import java.util.concurrent.*;
/**
* Alternate between ThreadA and ThreadB, displaying
* 5 (from ThreadA) and 8 (from ThreadB) in 10 columns, and 10 rows
*
* @author Grant Braught
* @author CSCI330
*/
public class SerializationExSem {
public static Semaphore aSem = new Semaphore(1);
public static Semaphore bSem = new Semaphore(0);
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
int[] x = { 1, 0 };
Thread threadA = new ThreadASem(x);
Thread threadB = new ThreadBSem(x);
threadA.start();
threadB.start();
try {
// wait for the threads to finish
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i % 10 == 0) {
// print a new line every 10 times
System.out.println();
} else {
// usually, print a tab
System.out.print("\t");
}
}
}
}
/**
* Sets x[0] = 5 and displays it
*/
class ThreadASem extends Thread {
private int[] x;
public ThreadASem(int[] x) {
this.x = x;
}
public void run() {
doWork();
try {
SerializationExSem.aSem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
x[0] = 5;
doWork();
System.out.print(x[0] + " ");
SerializationExSem.bSem.release();
}
public void doWork() {
for (int i = 0; i < 100000; i++) {
new Double(Math.random());
}
}
}
/**
* Sets x[1] to x[0] + 3 and displays x[1]
*/
class ThreadBSem extends Thread {
private int[] x;
public ThreadBSem(int[] x) {
this.x = x;
}
public void run() {
doWork();
try {
SerializationExSem.bSem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
x[1] = x[0] + 3;
doWork();
System.out.print(x[1] + " ");
SerializationExSem.aSem.release();
}
public void doWork() {
for (int i = 0; i < 100000; i++) {
new Double(Math.random());
}
}
}
./SodaMachineWithConditionVariable.java 8/9
[top][prev][next]
import java.util.concurrent.locks.*;
/**
* Another example of a producer-consumer problem:
* this time, a SodaMachine, using condition variables
*
* @author CSCI330
*/
class SodaMachineWithConditionVariable {
/* Shared State */
// made this kinda large, so you can better see the switching between threads
public static int maxSodas = 100;
public static int numSodas = 0;
// could also have a soda buffer
/* Synchronization Tools */
/** lock to update shared state */
public static final Lock sodaLock = new ReentrantLock();
/** the soda machine has space; producer can produce;
consumer notifies when takes a soda */
public static final Condition hasRoom = sodaLock.newCondition();
/** the soda machine has soda; consumer can consume;
producer notifies when adds a soda */
public static final Condition hasSoda = sodaLock.newCondition();
public static void main(String args[]) {
Thread producer = new SodaProducer(1);
Thread producer2 = new SodaProducer(2);
// can run with fewer producer/consumers. This just helps illustrate
// better what's happening with multiple threads.
Thread consumer = new SodaConsumer(1);
Thread consumer2 = new SodaConsumer(2);
producer.start();
consumer.start();
producer2.start();
consumer2.start();
}
}
class SodaProducer extends Thread {
private int id;
public SodaProducer( int id ) { this.id = id;}
public void run() {
while( true ) {
SodaMachineWithConditionVariable.sodaLock.lock();
while(SodaMachineWithConditionVariable.numSodas==SodaMachineWithConditionVariable.maxSodas){
try {
SodaMachineWithConditionVariable.hasRoom.await();
} catch( Exception e ) {
e.printStackTrace();
}
}
SodaMachineWithConditionVariable.numSodas++;
System.out.println(id + ": Adding a soda: " + SodaMachineWithConditionVariable.numSodas);
SodaMachineWithConditionVariable.hasSoda.signal();
SodaMachineWithConditionVariable.sodaLock.unlock();
}
}
}
class SodaConsumer extends Thread {
private int id;
public SodaConsumer(int id) { this.id = id; }
public void run() {
while( true ) {
SodaMachineWithConditionVariable.sodaLock.lock();
while (SodaMachineWithConditionVariable.numSodas == 0) {
try {
SodaMachineWithConditionVariable.hasSoda.await();
} catch( Exception e ) {
e.printStackTrace();
}
}
SodaMachineWithConditionVariable.numSodas--;
System.out.println(id + ": Remove a soda: " + SodaMachineWithConditionVariable.numSodas);
SodaMachineWithConditionVariable.hasRoom.signal();
SodaMachineWithConditionVariable.sodaLock.unlock();
}
}
}
./SodaMachineWithSemaphore.java 9/9
[top][prev][next]
import java.util.concurrent.*;
/**
* Another example of a producer-consumer problem:
* this time, a SodaMachine, using semaphores
*
* @author CSCI330
*/
class SodaMachineWithSemaphore {
/* Shared State */
// made this kinda large, so you can better see the switching between threads
public static int maxSodas = 2;
public static int numSodas = 0;
// could also have a soda buffer
/* Synchronization Tools */
/** lock to update shared state */
public static final Semaphore sodaLock = new Semaphore(1);
/** the soda machine has space; producer decrements -- if 0, waits to produce; consumer increments
*/
public static final Semaphore emptySlots = new Semaphore(maxSodas);
/** the soda machine has soda; consumer decrements -- if 0, waits to consumer; producer increments */
public static final Semaphore fullSlots = new Semaphore(0);
public static void main(String args[]) {
Thread producer = new SodaProducerSem(1);
Thread producer2 = new SodaProducerSem(2);
// can run with fewer producer/consumers. This just helps illustrate
// better what's happening with multiple threads.
Thread consumer = new SodaConsumerSem(1);
Thread consumer2 = new SodaConsumerSem(2);
producer.start();
consumer.start();
producer2.start();
consumer2.start();
}
}
class SodaProducerSem extends Thread {
private int id;
public SodaProducerSem( int id ) { this.id = id;}
public void run() {
while( true ) {
try {
SodaMachineWithSemaphore.emptySlots.acquire();
SodaMachineWithSemaphore.sodaLock.acquire();
} catch( InterruptedException e ) {
e.printStackTrace();
}
// the assert condition should never be true.
// checking because no explicit condition,
// as in condition variable solution
assert SodaMachineWithSemaphore.numSodas < SodaMachineWithSemaphore.maxSodas;
SodaMachineWithSemaphore.numSodas++;
System.out.println(id + ": Adding a soda: " + SodaMachineWithSemaphore.numSodas);
SodaMachineWithSemaphore.sodaLock.release();
SodaMachineWithSemaphore.fullSlots.release();
}
}
}
class SodaConsumerSem extends Thread {
private int id;
public SodaConsumerSem(int id) { this.id = id; }
public void run() {
while( true ) {
try {
SodaMachineWithSemaphore.fullSlots.acquire();
SodaMachineWithSemaphore.sodaLock.acquire();
} catch( InterruptedException e ) {
e.printStackTrace();
}
// the assert condition should never be true
assert SodaMachineWithSemaphore.numSodas > 0;
SodaMachineWithSemaphore.numSodas--;
System.out.println(id + ": Remove a soda: " + SodaMachineWithSemaphore.numSodas);
SodaMachineWithSemaphore.sodaLock.release();
SodaMachineWithSemaphore.emptySlots.release();
}
}
}
Generated by GNU Enscript 1.6.6.