In this assignment, you will learn how to access a collection from the Java Collections Framework in a thread-safe manner by using various thread synchronization techniques that are part of the Java language.
Your instructor may ask you to work in pairs.
Using multiple threads of execution is a powerful design paradigm that has many benefits when implemented correctly; for example, a well-designed applications can be much more responsive to user input even while carrying out complex activities in the background. On the downside, improper implementation of multi-threading can introduce unpredictable behavior due to insidious errors that can be difficult to detect. This is especially true when portions of the same code are executed on multiple threads. The official Javadoc for many libraries in Java (e.g. the collections framework and JavaFX) are full of warnings like “Note that this implementation is not synchronized”, meaning that incorporation of thread-safety is up to you, the user of the libraries.
Check your assignment to see whether you need to produce a report. If you do, use this report template to capture your findings. The rest of the document assumes you are creating the report, so ignore steps that do not pertain to you.
Assuming you are filling out the report, write your name and date at the top of the template. Write answers to any questions or other directions under the appropriate section heading. Do not simply copy thousands of lines of output to the report. Instead, capture snippets illustrating your points. Finally, ensure there are blank lines between paragraphs.
Begin by creating an application that implements the following class:
This code should be created in the package threading.part1
Within this application, the main()
method instantiates an instance of the
ThreadingApp class. Within the constructor, a secondary thread is to be
created and started that executes the addElements()
method. Immediately
following the start of the secondary thread, the addElements()
method should
be invoked (on the primary thread). This is illustrated in the following
sequence diagram. When the addElements() methods complete, join()
the
secondary thread to the primary thread and output the collection’s size
followed by the contents. Write both to the console.
Within the addElements()
method, implement a for()
loop that adds a
number of integer elements to the Collection as specified by the
count argument. (e.g. for this lab, specify a value for count of
10,000 in order to add the values 1 through 10,000 to the Collection).
Note that the Collection is declared as a List but is shown in the
class diagram as an ArrayList.
Run the application several times. Note that it may crash, but does it always crash? Why do you think it crashes? What is the result when it doesn’t crash? Is it what you expect? What is happening? Copy some interesting portions of the the output of the console to your report (described below), and record your observations. Note: it is not necessary to copy the entire console output (with thousands of values) to your report; just present a portion that is representative of the “interesting” behavior.
In each example explain the specific cause of the crash (if it does), and why the numbers come out the way they do.
Demonstrate this to your instructor before proceeding. (For this and all demonstrations, if the instructor is not available, continue to the next part, but be ready to demo this part when needed.)
Create a new package, threading.part2
. Copy the code from part 1 into this
package and then modify your code such that a LinkedList
is used instead
of an ArrayList
. Run the application again several times - the behavior
will differ from run to run. Copy the “interesting” console output to your
report and record your observations. Explain what you think is happening.
Demonstrate this to your instructor before proceeding.
Create a new package, threading.part3
. Copy the code from part 2 into this
package. Modify the addElements()
method, declaring the method
synchronized. (To do this, you simply add a synchronized keyword to
the method. This is the same as wrapping a single synchronize(this)
block
around the entire body of the method.) Run the application again several
times. Copy the console output to your report and record your observations,
specifically noting differences in behavior.
Demonstrate this to your instructor before proceeding.
Create a new package, threading.part4
. Copy the code from part 3 into this
package. Remove the synchronized
specifier from the addElements()
method. This time, implement a synchronized block within the
addElements()
method around the collection framework method calls, making
only access to the Collection synchronized. Run the application again several
times. Copy the console output to your report and record your observations.
In particular, be sure to identify differences in the output from parts 3 and 4.
Demonstrate this to your instructor before proceeding.
If you need to submit a lab report, review yours, checking that
If directed, upload your report to Canvas.
This exercise developed by MSOE faculty. The original version was developed by Dr. Mark Hornick.