02158  Concurrent Programming - Lab 1: Dynamic Java Thread Creation/Cancellation
Technical University of Denmark DTU
02158 Concurrent Programming        Fall 2024
Lab 1: Dynamic Java Thread Creation/Cancellation
Home Plan Material  

Purpose

To experiment with Java's mechanims for dynamically starting and terminating threads in connection with a rudimentary multi-threaded window application.

 
Furthermore, the lab will illustrate some effects of multiprocessing.

Time and Place

Assistance for this programming lab will be available in Building 303A, area EAST, Thursday September 12, 15.00-17.00

Preparations

You should consult [Proc 4] and perhaps [Andrews 5.4.1] to see how to create and terminate Java threads.

Instructions:

The objective of this lab is to control a number of tasks that each write in a textfield of a window.

 
The lab is easily run from the command line, but you may also import the files into a project of your favourite IDE.

  1. Make a new subdirectory/project for the exercise and fetch the files TaskControl.java and TaskDisplay.java.
  2. Compile and run TaskControl.java. Try to press the command keys 'h', 't' and 'x' and observe that the program does not react to key-presses (like 'h')) while running a Task.

     
    Explain this. How many threads are active in this program?

  3. Now modify TaskControl.java such that typing the command 't' runs a Task that writes in the first textfield using a dedicated background thread.  
    How does the system react now? What happens now if 't' is pressed while a Task is already running?
  4. Make sure that only one Task-thread is active at a time. Specifically, if a Task-thread is already running, a 't'-command should be rejected with an error message.

     
    Also, when terminating the program using command 'x', the termination of this thread must be awaited before closing the window (perhaps issuing status messages).

    To determine whether a started thread t is still active, t.isAlive() should be used. To await that it becomes terminated, t.join() should be used.

    Notice that a thread which has terminated cannot be restarted. Instead a new thread object must be created.

  5. Now, by pressing 't', is must be possible dynamically to start concurrent threads each writing in a separate textfield. If all fields are occupied by active threads, an error message should be issued. At exit, all active threads must have terminated before the window is closed.

     
    Hint: Use an array of Thread (or Task) to keep track of the active threads.

  6. Add the possibility of terminating an active Task by pressing '0', '1', ... etc. Try first to use t.stop() to stop a thread t.  
    Notice that the compiler will complain that the use of stop() is deprecated.
  7. In general, it is much more safe to cancel threads by letting them terminate themselves. A thread t may be urged to terminate itself by calling t.interrupt() which will set an interrupt flag associated with the thread. Now, the next call of a blocking operation in t (in this case sleep) will throw an InterruptedException (and clear the interrupt flag). Change the program such that the tasks terminate themselves and let them show with "'|'" where they were terminated.
  8. The given tasks mostly sleep during their execution and hence their speeds are largely independent of the number of running tasks and available processors. Now, we are going to change that in order to observe effects of multi-processing.

     
    Modify the Task to consume CPU-cycles by setting set the useCPU flag in run(). You may have to adjust the delay-factor of the inner loop in order to obtain a suitable speed (say 5-10 seconds to run a single task). The speed variation is automatically set to 0 to get comparable observations.

    Before starting more than one task at a time, try to predict the effect on the execution.

    Now try to see what happens when you start more than one tasks (almost) at the same time. Do you observe any speed reduction and for which numbers of tasks? Explain your observations.

    [If your computer has 4 or more cores, you may have to increase the number of text fields N in the source code to say 16 or 20 to see a speed reduction.]

  9. Observe, that the tasks cannot any longer be stopped by pressing '0', '1', ...!

     
    Explanation: Since sleep is no longer called regularly, the InterruptedException will not be thrown. Instead, a CPU-intensive task will have to use the boolean function interrupted() to test (and clear) the value of the interrupt flag where appropriate. Cancel the thread by this means.

  10. If you have more time, you may have a first look at Mandatory Assignment 1 which is released around 16.30.

    Meanwhile, you could try out Mini Lab 2.

Enjoy!

Notice

In most GUI-frameworks, such as the Swing-library used here, the window components are implemented all in Java, and for efficiency reasons not thread-safe. That means that only the event-dispatcher thread (aka the GUI thread) should call Swing components. By calling appropriate operations, other threads may post their updates within the event queue for subsequent processing by the event-dispatcher thread.

In the given program, the command handling is executed in a separate thread (actually the main thread) and key presses are sent via a buffer from the GUI thread to the command thread. To print on the display, the command thread uses the println() method which posts the printing to the event queue.

Also the Task-class has a method setMyText() which test whether the caller is the GUI thread or not. In the latter case, the method EventQueue.invokeLater() is used to post the text update on the event queue.

The Swing library provides the special class SwingWorker which facilitates asynchronous background execution. For details of using this, see the article:

http://docs.oracle.com/javase/tutorial/uiswing/concurrency

The same considerations apply to almost all GUI-frameworks, eg. .NET (WF, WPF), Eclipse SWT, JavaFX and Android which all provide specialized frameworks for doing asynchronous background processing.

Hans Henrik Løvengreen, Sep 12, 2024