[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

