CMPT 318 99-1: Assignment #3

Update: Feb 4

Due Date

Feb 22 during first break in class. There will be no late assignments accepted.

Marks

10% of your final mark

Purpose

This assignment builds experience in using Java's threading mechanism. Students will build appreciation for the important issues of thread creation, synchronization, lock spltting. The assignment should also build familiarity with producer/consumer method of thread synchronization. Students unfamiliar with some of the relevant Java syntax, and students still uncertain about MVC will benefit from modifying existing code.

Readings

  1. Read Eckel's Chapter 14: Multiple Threads. You do not have to worry about the section on Daemon Threads (pg. 767-768) or JavaBeans (780-784). Instead, pay close attention to the sections on synchronization and blocking.
  2. Read Sun's Tutorial section on Threads. You do not need to read the last sub-section on ThreadGroup (i.e. this). Instead, concentrate on the sub-sections on thread lifecycle and synchronization.

Questions

As is usual for these assignments, hand in the code that you have changed along with the answers to the written parts of the questions. Clarifications to this assignment will be sent to the mailing list if they are required.
  1. Thread States

    Every thread can be in a finite number of states, as detailed in Eckel, pg. 785. A thread's state can change, for instance, as a result of calling a thread-controlling function such as yield(). These changes are called state transitions. Draw a state-transition diagram showing all possible states and state transitions for a thread. Include all transitions in Java 1.1, even if they are deprecated in Java 1.2. When drawing state transition arrows, use a dashed lines to indicate a transition where object locks are not released by the thread, and use solid lines otherwise. Hand-drawn diagrams are quite acceptable if they are tidy.

    n.b. a state-transition diagram shows states as blocks and transitions as labelled arrows, and is therefore a labelled directed graph. A partial state-transition diagram is shown in Sun's Java tutorial, and this was also presented this in class. For example, in that diagram "The run method terminates" and "yield" are labelled edges and "Dead" is a state. You should have a different edge in the graph for every possible transition method.

    (5 marks)

  2. Simple Threading

    Here is a simple program that does sorting on a number of vectors of data. As written, the sorting is sequential and runs in a single thread (as indicated by the comment on line 9). You must modify the class Sorter to make each of the separate NUM_VECTORS sort operations occur in parallel in separate threads. You should not modify in any way the class a3q1 or the method Sorter.bubblysort(). It should still be possible to change NUM_VECTORS to any number. Answer the following questions using at most a few short sentences.

    1. Why is it ok to avoid synchronizing bubblysort()? (1 mark)

    2. Notice the order and time at which the output occurs. Describe what happens and why. (2 marks)

    3. There are two comments within bubblysort(): one with a yield() call and one with a sleep() call. Uncomment them one at a time and describe what the differences are, if any, on the execution times and output times. (1 mark).

    4. Depending upon your Java implementation (and operating system), uncommenting the comments above can have different effects. If you noticed an effect on the output, explain why the added call in question modified the running behaviour. If you did not notice any effect, explain why. (You might want to try the program out on more than one JRE) (2 marks)

    5. What happens when you add a synchronized modifier to the definition of method bubblysort()? Why? (1 mark)

    Note: you may have to tweak the value of VECTOR_SIZE in order to get reasonable (i.e. a minute or two) waiting times, depending upon your JRE and system speed.

    (10 marks total)   Remember to hand in your code.

    Some hints: it is possible to modify the code so that it correctly works without any synchronized sections. You may not be able to avoid synchronization without using inner classes. The state-transition diagram you drew in question 1 might help you out in this question.

  3. Producer/Consumer

    One of the most important reasons for using multi-threading in Java is to provide responsive interfaces (see Eckel, beginning of chapter 14). In Assignment #2, the search interface was not responsive (regardless of whether you used dummy query values or not) because it waited until all the results were downloaded before beginning to display them to the user.

    You can fix the responsiveness of this application by using multiple threads. As was discussed in class, this can be done by making the downloading and display updates occur within separate threads. You are provided the source code for a simple, singly-threaded query tool source here. You are to modify the ResultsModel class as neccessary in order to make the downloading and display updating occur in separate threads.

    The following points are to be considered when making your solution:

    1. Reading of the data from the network requires the use of blocking I/O operations. In order to make interface update responsive despite these blocking operations, you must read data from the network within a separate thread.

    2. ResultsModel should notify its Observers as data is received from the network. This makes the interface responsive even for long query results or during network delays.

    3. Since interface actions should be attended to quickly, you should make sure that setQuery() returns quickly since it will be called by the UI's event-handling thread. Thus your Observer notification should be performed in a separate thread.

    4. Your threads should communicate as simple producer/consumer pair (See Sun's example). Since Observer notification may take significant time, you should make sure that your producer's output can be buffered if the consumer cannot catch up to the producer.

    5. You must be sure to comply with the AbstractResultsModel subclassing rules.

    You need only turn in the the ResultsModel and any other classes you create. (Do not change any of the other classes given to you).

    Make sure you clearly document your code, and include (a) descriptions of what resources are locked, by whom, and when, and (b) how the subclassing constraints of AbstractResultsModel are satisfied by your code.

    Note there are some implementation hints prepared.

    (20 marks)