Menu

[Solved] Part 1 First Program Add Synchronization Using Semaphores Program Reads Displays File Howe Q37197670

Part 1:

In the first program, you will add synchronization (usingsemaphores) to a program that reads and displays a file. However,the file is read by some number of threads as indicated by theprograms command line arguments.

A starter program for you to work from for this part of theassignment is provided. The program uses command line

arguments as so:

java FileThreads InputFile.txt <num-threads>

where InputFile.txt is the input file the threads read (it couldbe called anything, but I supply a file called InputFile.txt) and<num-threads> is the number of threads to start (must be lessthan 15). To run the program in Jgrasp with command line argument,go the the Build menu and click Run Arguments. This will open atextfield above the edit area in which you can type the commandline arguments.

The main method verifies that the command line arguments existand are valid (the file exists and can be opened, and the number ofthreads is less than or equal to 15). The main method then createsa private log (as a StringBuilder class object) for each thread,creates a runnable object (giving the private log and index asarguments to the constructor), and then starts the thread.

The run method is shown on the next page. The input file is aJava FileReader object, which supports the read() method. Theread() returns an integer value that either represents thecharacter read from the file, or is -1 to represent the end of thefile. The read() method also can throw an IOException, which iscaught. After the call to the read() method, Thread.sleep() iscalled to put in a random delay. Since the Thread.sleep() can throwan Interrupted Exception, this is also caught. Note that in any ofthe situations for end the thread’s reading of the file (end offile, IOException, or InterruptedException), the behavior is thesame: make all threads stop.

After the Thread.sleep() method returns, the character that wasread is added to the end of the main log (in the variable mainLog)and to the end of the thread private log (in the variablemyLog).

When this program is run as is (unless you run it with only onethread), you’ll note that the display of the main log is nothinglike the original file. In fact, you may find that the programoccasionally throws an ArrayOutOfBoundsException on the append toone of the logs. The task for this part of the assignment is toidentify the critical section of the run method, define andinitialize a binary semaphore, and use the semaphore acquire() andrelease() methods to protect the critical section. Remember, when athread acquires the semaphore, it must eventually release it forcorrect behavior, no matter what path through the code istaken.

Part 2:

The next part requires you to add a set of counting semaphoresto the provided Java program to solve the Tea Drinkers Problem. Theprogram again requires command line arguments and is called as

java TeaParty <num-threads>

where <num-threads> is the number of threads to start. Inthe description of the problem that follows, n is the number ofthreads.

The Tea Drinkers Problem: A group of n tea drinkers sit around atable to drink tea and talk. To drink tea, each tea drinkerrequires a cup, a saucer, and a spoon and tea drinker cannot drinktea until the tea drinker has all three. There are only n-1 cups,n-1 saucers, and n-1 spoons but any tea drinker can take any cup,saucer, or spoon as long as it is free. Each tea drinker isrepresented by a runnable class with the run method shown on thenext page.

You will use this class as an inner class of a public classcalled TeaParty. This class will also define a set of semaphoresthat are used to synchonize the tea drinker threads in their use ofthe cups, saucers, and spoons. The main method of TeaParty willinitialize the semaphore counts (you will use counting semaphores,one for each of the three items the tea drinkers need) and then themain method will create and start n TeaDrinker threads (you mainmethod should get the value for n from the String array parameterof the main method.

Add code in the highlighted area to use the semaphores tosynchronize the tea drinkers to use the n-1 sets of cup, saucers,and spoons.

Submit your Java program TeaParty.java for this part of theproject as part of your zip archive file.

The Java Semaphore class is defined in the java.util.concurrentpackage. The semaphore methods that you will need to use are:

•Semaphore(int permits), the constructor. permits is the intialvalue for the semaphore count.

• void acquire() Acquires a permit from this semaphore, blockinguntil one is available, or the thread is interrupted. acquire()throws the InterruptedException and must be used in a try-catchblock.

• void release() Releases a permit, returning it to thesemaphore. No exception is thrown by this method.

Thread.java:

import java.io.*;

import java.util.*;

import java.util.concurrent.*;

public class FileThreads implements Runnable {

// file shared by the threads

static FileReader inputFile = null;

// a string that each thread uses to log the character itreads

static StringBuilder [] threadLogs = null;

// the main log that all threads write into

static StringBuilder mainLog = new StringBuilder();

// a flag that tells the threads to keep working

static volatile boolean keepgoing = false;

// a thread private variable that holds the private threadlog

StringBuilder myLog;

// a thread private variable that identifies the thread

int me;

// the constructor that saves the log and id number to

// the thread private variables

public FileThreads(StringBuilder sb, int i) {

myLog = sb;

me = i;

}

// the thread program

public void run() {

// use to generate a sleep between readng from the input

file

// and writing the character read

Random r = new Random(System.nanoTime());

// this loop holds the worker threads until the main

thread has started

// them all

while(! keepgoing) /* Empty statement */ ;

// a count for the display statement each thread prints

// if the count display stops without the final results,

there

// may be a problem in your semaphore code.

int count = 1;

// main loop

while(keepgoing) {

System.out.println(“Thread ” + me + ” read “

+ count++); // count display

int c;

// to read the

next character

try {

if((c = inputFile.read()) < 0) {

// if read() returns -1 end of file

keepgoing = false;

// stop the threads

System.out.println(“Thread “

+ me + ” is finished<*>”);

return;

}

Thread.sleep((r.nextInt(5)+1)*10);

// sleep

} catch(IOException ie) {

// read can throw this

System.out.println(“Caught IOException

in thread ” + me);

keepgoing = false;

return;

} catch(InterruptedException iex) {

// sleep can throw this

System.out.println(“Caught

InterruptedException from sleep()”);

keepgoing = false;

return;

}

mainLog.append((char) c);

// add character to main log

myLog.append((char) c);

// add character to private

log

}

System.out.println(“Thread ” + me + ” isfinished<*>”);

}

public static void main(String [] args) {

// the first 25 lines of code deal with command line

arguments, getting the number of threads

// and the file name and handling errors

if(args.length != 2) {

System.err.println(“Need a file name followed

by the number of threads to run (less than 15)”);

System.exit(-1);

}

int numThreads = 0;

try {

numThreads = Integer.parseInt(args[1]);

if (numThreads > 15) {

System.err.println(“Can’t start more

than 15 threads; you tried to start ” + args[1]);

System.exit(-1);

}

}catch(NumberFormatException infe) {

System.err.println(“Second argument must be a

number less than or equal to 15; you gave ” + args[1]);

System.exit(-1);

}

try {

inputFile = new FileReader(args[0]);

} catch(FileNotFoundException fnfe) {

System.out.println(“Could not open file ” +

args[0] + “; check spelling.”);

System.exit(-1);

}

// all allocate storage for these arrays

threadLogs = new StringBuilder[numThreads];

Thread [] t = new Thread[numThreads];

// this loop creates the thread private logs, the

runnable objects and starts the threads

for(int i = 0; i < numThreads; i++) {

System.out.println(“Main thread starting

thread ” + i);

threadLogs[i] = new StringBuilder(“Thread ” +

i + “: “);

t[i] = new Thread(new

FileThreads(threadLogs[i], i));

t[i].start();

}

keepgoing = true;

// release the threads

for(int i = 0; i < numThreads; i++)

// wait for the threads to complete

try {

t[i].join();

}catch(InterruptedException ie) {}

System.out.println(“printing thread logs:”);

for(int i = 0; i < numThreads; i++) {

// display the thread private logs

System.out.print(“Thread ” + i + ” log: “);

System.out.println(“<<<<t” +

threadLogs[i].toString() +

“>>>>”);

}

System.out.println(“Printing main log: “); //

display the main log

System.out.println(mainLog.toString());

}

}

File.txt:

3. Coat a large bowl with nonstick spray and transfer dough tobowl,

turning to coat. Cover with

plastic wrap and let rise in a warm, draft-free place untildoubled in

size, about 1 hour.

4. If making rolls, lightly coat a 6-cup jumbo muffin pan withnonstick

spray. Turn out dough

onto a floured surface and divide into 6 pieces. Divide eachpiece into 4

smaller pieces

(you should have 24 total). They don’t need to be exact; justeyeball it.

Place 4 pieces of dough

side-by-side in each muffin cup.

If making loaves, lightly coat two 9- by 5-inch loaf pans withnonstick

spray. Turn out dough

onto a floured surface and divide into 12 pieces. Nestle piecesside-by-

side to create 2 rows

down length of each pan.

If making split-top buns, lightly coat two 9- by 13-inch bakingdishes

with nonstick spray.

Divide dough into 12 pieces and shape each into a 4-inch longlog. Place

6 logs in a row down

length of each dish.

5. Let shaped dough rise in a warm, draft-free place untildoubled in size

(dough should be just

puffing over top of pan), about 1 hour.

6. Preheat oven to 375 degrees F. Beat remaining egg with 1teaspoon.

water in a small bowl to

blend. Brush top of dough with egg wash and sprinkle with seasalt, if

desired. Bake, rotating

pan halfway through, until bread is deep golden brown, startingto pull

away from the sides of

the pan, and is baked through, 25 to 35 minutes for rolls, 50 to60

minutes for loaf, or 30 to 40

minutes for buns. If making buns, slice each bun down the middledeep

enough to create a split-top.

Let milk bread cool slightly in pan on a wire rack beforeturning out; let

cool completely.

TeaParty.java:

import java.util.concurrent.*;

import java.util.*;

public class TeaParty {

static class TeaDrinker implements Runnable {

private int myID;

private int mySleepTimeNS;

public TeaDrinker(int id, int sleep) {

myID = id;

mySleepTimeNS = sleep;

}

private void sleep(int t) {

try {

Thread.sleep(t);

} catch (InterruptedException ie) {

System.out.println(“Sleep interrupted;

should not happen”);

}

}

public void run() {

System.out.println(“Tea drinker ” + myID +

” starting after sleep of “

+ mySleepTimeNS + “ns”);

sleep(mySleepTimeNS);

while (true) { // run for ever

sleep(mySleepTimeNS);

System.out.println(“Tea drinker ” +

myID + ” getting cup, saucer, and spoon”);

// add code to get the cup, saucer, and

spoon here

System.out.println(“Tea drinker ” +

myID +

” drinking tea

for ” + mySleepTimeNS + “ns”);

sleep(mySleepTimeNS);

System.out.println(“Tea drinker ” +

myID +

” finished

drinking tea, releasing cup, saucer, and spoon”);

// add code to release the cup, saucer,

and spoon here

System.out.println(“Tea drinker ” +

myID +

” will talk for ” +

mySleepTimeNS + “ns”);

sleep(mySleepTimeNS);

}

}

}

public static void main(String [] args) {

if (args.length != 1) {

System.err.println(“Need the number of

threads as an argument”);

System.exit(-1);

}

int numThreads = 0;

try {

numThreads = Integer.parseInt(args[0]);

} catch (NumberFormatException nfe) {

System.err.println(“Need an intege”); System.exit(-1); }

Thread [] threads = new Thread[numThreads];

Random r = new Random(100);

for(int i = 0; i < numThreads; i++) {

threads[i] = new Thread(new TeaDrinker(i,

(r.nextInt(5) + 1) * 500));

}

for(int i = 0; i < numThreads; i++)

threads[i].start();

}

}

Expert Answer


Answer to Part 1: In the first program, you will add synchronization (using semaphores) to a program that reads and displays a fil… . . .

OR


Leave a Reply

Your email address will not be published. Required fields are marked *