The purpose of this assignment is to acquire understanding and experience with concurrency in the context of the Java Programming Language.
This assignment is composed of several small Java programs that will be utilized to explore several features of concurrency primitives support supported by the Java Programming Language:
1. Below is a UML state diagram that shows the Java thread life cycle.
Use the following implementation and write a short implementation class called ThreadCreator that will start three PrintTask threads. Execute the PrintTask 5 times and analyze the output for the following: a) variations in task sleep time and variations in the order of tasks switching.
1 //
2 // PrintTask
class sleeps for a random time from 0 to 5 seconds
3 import
java.util.Random;
4
5 public class
PrintTask implements Runnable
6 {
7 private final int sleepTime; // random sleep time for thread
8 private final String taskName; // name of task
9 private final static Random generator = new
Random();
10
11 public
PrintTask( String name )
12 {
13 taskName = name; // set task name
14
15 // pick random
sleep time between 0 and 5 seconds
16 sleepTime = generator.nextInt( 5000 ); //
milliseconds
17 } // end
PrintTask constructor
18
19 // method run
contains the code that a thread will execute
20 public void
run()
21 {
22 try // put thread to sleep for sleepTime amount of time
23 {
24 System.out.printf( "%s going to sleep for %d milliseconds.\n",
25 taskName, sleepTime );
26 Thread.sleep( sleepTime ); // put thread to sleep
27 } // end try
28 catch
( InterruptedException exception )
29 {
30 System.out.printf( "%s %s\n", taskName,
31 "terminated
prematurely due to interruption" );
32 } // end
catch
33
34 // print
task name
35 System.out.printf( "%s done sleeping\n", taskName );
36 } // end method
run
37
} // end class PrintTask
Below is a hint for the ThreadCreator class:
3 import java.lang.Thread;
4
5 public class ThreadCreator
6 {
7 public static void main( String[] args )
8 {
9 System.out.println( "Creating threads" );
10
11 // create each thread with a new targeted runnable
12 Thread thread1 = new Thread( new PrintTask( "task1" ) );
13
14
15
16 System.out.println( "Threads created, starting tasks." );
17
18 // start threads and place in runnable state
19 thread1.start(); // invokes task1's run method
20
21
22
23 System.out.println( "Tasks started, main ends.\n" );
24 } // end main
25 } // end class RunnableTester
1. The purpose of this problem is to demonstrate inserting two values into a shared array that has not been implemented with thread synchronization. Compile and execute the Java code below and analyze the output. What did you observe on your machine with respect to this unsynchronized implementation?
1 //
2 // Class that manages an integer array to be shared by multiple threads.
3 import java.util.Random;
4
5 public class SimpleArray // CAUTION: NOT THREAD SAFE!
6 {
7 private final int array[]; // the shared integer array
8 private int writeIndex = 0; // index of next element to be written
9 private final static Random generator = new Random();
10
11 // construct a SimpleArray of a given size
12 public SimpleArray( int size )
13 {
14 array = new int[ size ];
15 } // end constructor
16
17 // add a value to the shared array
18 public void add( int value )
19 {
20 int position = writeIndex; // store the write index
21
22 try
23 {
24 // put thread to sleep for 0-499 milliseconds
25 Thread.sleep( generator.nextInt( 500 ) );
26 } // end try
27 catch ( InterruptedException ex )
28 {
29 ex.printStackTrace();
30 } // end catch
31
32 // put value in the appropriate element
33 array[ position ] = value;
34 System.out.printf( "%s wrote %2d to element %d.\n",
35 Thread.currentThread().getName(), value, position );
36
37 ++writeIndex; // increment index of element to be written next
38 System.out.printf( "Next write index: %d\n", writeIndex );
39 } // end method add
40
41 // used for outputting the contents of the shared integer array
42 public String toString()
43 {
44 String arrayString = "\nContents of SimpleArray:\n";
45
46 for ( int i = 0; i < array.length; i++ )
47 arrayString += array[ i ] + " ";
48
49 return arrayString;
50 } // end method toString
51 } // end class SimpleArray
1 //
2 // Adds integers to an array shared with other Runnables
3 import java.lang.Runnable;
4
5 public class ArrayWriter implements Runnable
6 {
7 private final SimpleArray sharedSimpleArray;
8 private final int startValue;
9
10 public ArrayWriter( int value, SimpleArray array )
11 {
12 startValue = value;
13 sharedSimpleArray = array;
14 } // end constructor
15
16 public void run()
17 {
18 for ( int i = startValue; i < startValue + 3; i++ )
19 {
20 sharedSimpleArray.add( i ); // add an element to the shared array
21 } // end for
22 } // end method run
23 } // end class ArrayWriter
1 //
2 // Executes two Runnables to add elements to a shared SimpleArray.
3 import java.util.concurrent.Executors;
4 import java.util.concurrent.ExecutorService;
5 import java.util.concurrent.TimeUnit;
6
7 public class SharedArrayTest
8 {
9 public static void main( String[] arg )
10 {
11 // construct the shared object
12 SimpleArray sharedSimpleArray = new SimpleArray( 6 );
13
14 // create two tasks to write to the shared SimpleArray
15 ArrayWriter writer1 = new ArrayWriter( 1, sharedSimpleArray );
16 ArrayWriter writer2 = new ArrayWriter( 11, sharedSimpleArray );
17
18 // execute the tasks with an ExecutorService
19 ExecutorService executor = Executors.newCachedThreadPool();
20 executor.execute( writer1 );
21 executor.execute( writer2 );
22
23 executor.shutdown();
24
25 try
26 {
27 // wait 1 minute for both writers to finish executing
28 boolean tasksEnded = executor.awaitTermination(
29 1, TimeUnit.MINUTES );
30
31 if ( tasksEnded )
32 System.out.println( sharedSimpleArray ); // print contents
33 else
34 System.out.println(
35 "Timed out while waiting for tasks to finish." );
36 } // end try
37 catch ( InterruptedException ex )
38 {
39 System.out.println(
40 "Interrupted while wait for tasks to finish." );
41 } // end catch
42 } // end main
43 } // end class SharedArrayTest
2. Modify the code in problem two to be synchronized. Hint: only one line in the SimpleArray class need to be modified to convert problem two for synchronization. HintHint: inspect the add method in the SimpleArray class as a potential candidate for synchronization. Compare the output against problem 2.