Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

The first thing to do is increase the buffer size. Rather than hardcoding in a value add an integer parameter to the BlockingBuffer constructor. Use

The first thing to do is increase the buffer size. Rather than hardcoding in a value add an integer parameter to the BlockingBuffer constructor. Use that value to set the size of the buffer, the new ArrayBlockingQueue. You will need to add an integer parameter to the call to the BlockingBuffer constructor in main in BlockingBufferTest, use the value 10. Execute the program and it should run as before, but you will most likely see that 2 or even 3 Buffer cells are occupied during execution.

Make the following changes to the Producer class:

  • Add four data members: name, a string; sleepTime, an integer; startProducing, an integer; and stopProducing, an integer.
  • Modify the constructor so that initial values for each of these data members is passed in along with the Buffer sharedLocation parameter.
  • Make the following changes to the run method:
    • Change the for loop so that it goes from startProducing to stopProducing rather than 1 to 10.
    • Change the sleep time from 3000 to sleepTime * 1000.
    • Change the output line at the end so that it outputs the producers name. If the producers name is, for example, P1, the message display should be Producer P1 done producing with Terminating Producer P1 on the next line.

With the changes to the Producer class you will need to change the constructor call in main. Pass in the value P1 for name, 10 for startProducing, 19 for stopProducing, and 2 for sleepTime. If all of the changes were done correctly your program should now run. You should see the values 10..19 are produced, and you should see Producer P1 done producing followed by Terminating Producer P1.

Now make the following changes to the Consumer class:

  • Add four data members: name, a string; sleepTime, an integer; startConsuming, an integer; and stopConsuming, an integer.
  • Modify the constructor so that initial values for each of these data members is passed in along with the Buffer sharedLocation parameter.
  • Make the following changes to the run method:
    • Change the for loop so that it goes from startConsuming to stopConsuming rather than 1 to 10.
    • Change the sleep time from 3000 to sleepTime * 1000.
    • Change the output line at the end so that it outputs the consumers name. If the consumers name is, for example, C1, the message display should be Consumer C1 read values totaling followed by the sum, with Terminating Consumer C1 on the next line.

With the changes to the Consumer class you will need to change the constructor call in main. Pass in the value C1 for name, 1 for startConsuming, 10 for stopConsuming, and 4 for sleepTime. If all of the changes were done correctly your program should now run. You should see that values 11..20 are consumed, and the output should end with Consumer C1 read values totaling 155 followed by Terminating Consumer C1.

There is a comment in BlockingBufferTest that is in error, the one that says create new thread pool with two threads. The program may be creating two threads, but it can create as many as you want. Change the comment to create new thread pool with multiple threads.

Create two additional producers. Name one P2 with start value 20, stop value 24, sleep time 2. Name the other P3 with start value 30, stop value 34, sleep time 3. Create another consumer. Name it C2 with start value 1, stop value 10, and sleep time 2.

Recall that the run method in the Producer class never does anything with the variable sum other than add to it. When the method is finished sum contains the total of the values written to the buffer, similar to the way the consumer totals and displays the sum of the values read. Put the variable sum to use by modifying the final output of the run method so that it displays the sum of the values produced as shown in the following example: Producer P1 produced values totaling 145 Terminating Producer P1

Your program should now run. You should see that several items are produced and consumed. You should also see that each producer and consumer terminated. The output, however, does not identify the individual producers and consumers in the output. To do that youll have to modify the BlockingBuffer and the Buffer interface.

Add a string parameter called name to blockingPut in the Buffer interface. Similarly add a string parameter called name to blockingGet. Add those parameters to the blockingPut and blockingGet methods in the class BlockingBuffer. Modify the print statement in each method so that the name of the producer or consumer is displayed as in the following examples:

  • Producer P2 writes 20 Buffer cells occupied: 1
  • Consumer C2 reads 20 Buffer cells occupied: 0

Now change the calls to blockingPut and blockingGet in the Producer and Consumer classes so that their names are passed as arguments.

Your program should now run, and the output should be readily identifiable as to which items were produced by each producer and which items were consumed by each consumer. Note that some things are still hardcoded into BlockingBufferTest. You can tell each producer how many items to produce and tell each consumer how many items to consume. You must, however, manually ensure that the total number of items produced is equal to the total number of items consumed. Currently P1 produces 10 items, P2 produces 5 items, and P3 produces 5 items, for a total of 20 items. C1 and C2 each consume 10 items for a total of 20 items. You also have the total of the values produced/consumed for each producer/consumer. The totals for all three producers should be the same as the totals for the two consumers. To check this you have to manually get the values from the output, add them together, and compare them.

When you are finished experimenting with the various parameter values, set them as follows:

  • Buffer size: 5
  • P1: start 10, stop 16, sleep 2
  • P2: start 25, stop 29, sleep 3
  • P3: start 30, stop 39, sleep 1
  • C1: start 1, stop 9, sleep 3
  • C2: start 1, stop 13, sleep 2

Sample Output

Producer P1 writes 10 Buffer cells occupied: 0 Consumer C2 reads 10 Buffer cells occupied: 0 Producer P3 writes 30 Buffer cells occupied: 1 Consumer C2 read values totaling 297 Terminating Consumer C2

BlockingBuffer.Java

// Creating a synchronized buffer using the ArrayBlockingQueue class.

import java.util.concurrent.ArrayBlockingQueue;

public class BlockingBuffer implements Buffer

{

private final ArrayBlockingQueue buffer; // shared buffer

public BlockingBuffer()

{

buffer = new ArrayBlockingQueue(1);

}

// place value into buffer

public void blockingPut(int value) throws InterruptedException

{

buffer.put(value); // place value in buffer

System.out.printf("%s%2d\t%s%d%n", "Producer writes ", value,

"Buffer cells occupied: ", buffer.size());

}

// return value from buffer

public int blockingGet() throws InterruptedException

{

int readValue = buffer.take(); // remove value from buffer

System.out.printf("%s %2d\t%s%d%n", "Consumer reads ",

readValue, "Buffer cells occupied: ", buffer.size());

return readValue;

}

} // end class BlockingBuffer

BlockingBufferTest.Java

// Two threads manipulating a blocking buffer that properly

// implements the producer/consumer relationship.

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

public class BlockingBufferTest

{

public static void main(String[] args) throws InterruptedException

{

// create new thread pool with two threads

ExecutorService executorService = Executors.newCachedThreadPool();

// create BlockingBuffer to store ints

Buffer sharedLocation = new BlockingBuffer();

executorService.execute(new Producer(sharedLocation));

executorService.execute(new Consumer(sharedLocation));

executorService.shutdown();

executorService.awaitTermination(1, TimeUnit.MINUTES);

}

} // end class BlockingBufferTest

Buffer.Java

// Buffer interface specifies methods called by Producer and Consumer.

public interface Buffer

{

// place int value into Buffer

public void blockingPut(int value) throws InterruptedException;

// obtain int value from Buffer

public int blockingGet() throws InterruptedException;

} // end interface Buffer

Consumer.Java

// Consumer with a run method that loops, reading 10 values from buffer.

import java.security.SecureRandom;

public class Consumer implements Runnable

{

private static final SecureRandom generator = new SecureRandom();

private final Buffer sharedLocation; // reference to shared object

// constructor

public Consumer(Buffer sharedLocation)

{

this.sharedLocation = sharedLocation;

}

// read sharedLocation's value 10 times and sum the values

public void run()

{

int sum = 0;

for (int count = 1; count <= 10; count++)

{

// sleep 0 to 3 seconds, read value from buffer and add to sum

try

{

Thread.sleep(generator.nextInt(3000));

sum += sharedLocation.blockingGet();

}

catch (InterruptedException exception)

{

Thread.currentThread().interrupt();

}

}

System.out.printf("%n%s %d%n%s%n",

"Consumer read values totaling", sum, "Terminating Consumer");

}

} // end class Consumer

Producer.Java

// Producer with a run method that inserts the values 1 to 10 in buffer.

import java.security.SecureRandom;

public class Producer implements Runnable

{

private static final SecureRandom generator = new SecureRandom();

private final Buffer sharedLocation; // reference to shared object

// constructor

public Producer(Buffer sharedLocation)

{

this.sharedLocation = sharedLocation;

}

// store values from 1 to 10 in sharedLocation

public void run()

{

int sum = 0;

for (int count = 1; count <= 10; count++)

{

try // sleep 0 to 3 seconds, then place value in Buffer

{

Thread.sleep(generator.nextInt(3000)); // random sleep

sharedLocation.blockingPut(count); // set value in buffer

sum += count; // increment sum of values

}

catch (InterruptedException exception)

{

Thread.currentThread().interrupt();

}

}

System.out.printf(

"Producer done producing%nTerminating Producer%n");

}

} // end class Producer

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Introductory Relational Database Design For Business With Microsoft Access

Authors: Jonathan Eckstein, Bonnie R. Schultz

1st Edition

1119329418, 978-1119329411

More Books

Students also viewed these Databases questions