Recent Changes - Search:

Network Programming

This website demonstrates using wikis as teaching and learning tool.

The course instructor is happy to share the teaching materials here with those who find it readable.

Java Programming - Multithreading

A Network Programming Lecture by Steven Choy

Lecture Overview: Introduction to Multithreading - Creating and Running Threads in Java - Thread Subclass - Runnable Implementation - Other Major Thread Concepts


Introduction

  • Multithreading is the ability to simultaneously have multiple points of execution which are called threads.
  • Why should a program need to use multiple threads?
  • Multithreading can have several benefits. Some of these benefits are:
    • Better resource utilization
    • Simpler program design in some situations
    • More responsive programs
Examples
Single-threaded program flow
      5 seconds reading file A
      2 seconds processing file A
      5 seconds reading file B
      2 seconds processing file B
    -----------------------
     14 seconds total
Multi-threaded program flow
      5 seconds reading file A
      5 seconds reading file B + 2 seconds processing file A
      2 seconds processing file B
    -----------------------
     12 seconds total
Benefits: Better resource utilization, Simpler program design
"If you were to program the above ordering of reading and processing by hand in a singlethreaded application, you would have to keep track of both the read and processing state of each file. Instead you can start two threads that each just reads and processes a single file. Each of these threads will be blocked while waiting for the disk to read its file. While waiting, other threads can use the CPU to process the parts of the file they have already read. The result is, that the disk is kept busy at all times, reading from various files into memory. This results in a better utilization of both the disk and the CPU. It is also easier to program, since each thread only has to keep track of a single file."
Benefit: More responsive programs
"Imagine a server application that listens on some port for incoming requests. when a request is received, it handles the request and then goes back to listening. The server loop is sketched below:"
        while(server is active){
          listen for request
          process request
        }
"If the request takes a long time to process, no new clients can send requests to the server for that duration. Only while the server is listening can requests be received."
"An alternate design would be for the listening thread to pass the request to a worker thread, and return to listening immediatedly. The worker thread will process the request and send a reply to the client. This design is sketched below:"
        while(server is active){
          listen for request
          hand request to worker thread
        }
"This way the server thread will be back at listening sooner. Thus more clients can send requests to the server. The server has become more responsive."

Creating and running threads

  • There are two ways of creating threads in Java, namely:
    • extending the Thread class
    • implementing the Runnable interface

Thread Subclass

  • Steps to create and start a thread:
  • 1) Create a subclass of the Thread class, and override the run method to perform the task of the new thread.
        public class MyThread extends Thread {

          public void run(){
             System.out.println("MyThread running"); 
          }
        }
  • 2) Create an instance of the subclass.
        MyThread myThread = new MyThread();
  • 3) Invoke the start method on the subclass instance.
        myTread.start();

Runnable implemention

  • To create a thread using the Runnable interface, follow these steps:
  • 1) Create a class that implements the Runnable interface, and supply a run method to perform the task of the new thread.
        public class MyRunnable implements Runnable {

          public void run(){
             System.out.println("MyRunnable running");
          }
        }
  • 2) Create an instance of the new class, and use it to create a Thread by the Thread(Runnable) or Thread(Runnable, String) constructor.
      Thread thread = new Thread(new MyRunnable());
  • 3) Invoke the start method on the Thread object.
      thread.start();

Examples

  • Here is an example that creates a new thread and starts it running:
  1. // Create a new thread.
  2. class NewThreadOne implements Runnable {
  3.    Thread t;
  4.    NewThreadOne() {
  5.       // Create a new, second thread
  6.       t = new Thread(this, "Demo Thread");
  7.       System.out.println("Child thread: " + t);
  8.       t.start(); // Start the thread
  9.    }
  10.  
  11.    // This is the entry point for the second thread.
  12.    public void run() {
  13.       try {
  14.          for(int i = 5; i > 0; i--) {
  15.             System.out.println("Child Thread: " + i);
  16.             // Let the thread sleep for a while.
  17.             Thread.sleep(500);
  18.          }
  19.      } catch (InterruptedException e) {
  20.          System.out.println("Child interrupted.");
  21.      }
  22.      System.out.println("Exiting child thread.");
  23.    }
  24. }
  25.  
  26. class ThreadDemo {
  27.    public static void main(String args[]) {
  28.       new NewThreadOne(); // create a new thread
  29.       try {
  30.          for(int i = 5; i > 0; i--) {
  31.            System.out.println("Main Thread: " + i);
  32.            Thread.sleep(1000);
  33.          }
  34.       } catch (InterruptedException e) {
  35.          System.out.println("Main thread interrupted.");
  36.       }
  37.       System.out.println("Main thread exiting.");
  38.    }
  39. }
  • Here is the preceding program rewritten to extend Thread:
  1. // Create a second thread by extending Thread
  2. class NewThreadTwo extends Thread {
  3.    NewThreadTwo() {
  4.       // Create a new, second thread
  5.       super("Demo Thread");
  6.       System.out.println("Child thread: " + this);
  7.       start(); // Start the thread
  8.    }
  9.  
  10.    // This is the entry point for the second thread.
  11.    public void run() {
  12.       try {
  13.          for(int i = 5; i > 0; i--) {
  14.             System.out.println("Child Thread: " + i);
  15.             // Let the thread sleep for a while.
  16.             Thread.sleep(500);
  17.          }
  18.       } catch (InterruptedException e) {
  19.          System.out.println("Child interrupted.");
  20.       }
  21.       System.out.println("Exiting child thread.");
  22.    }
  23. }
  24.  
  25. class ExtendThread {
  26.    public static void main(String args[]) {
  27.       new NewThreadTwo(); // create a new thread
  28.       try {
  29.          for(int i = 5; i > 0; i--) {
  30.             System.out.println("Main Thread: " + i);
  31.             Thread.sleep(1000);
  32.          }
  33.       } catch (InterruptedException e) {
  34.          System.out.println("Main thread interrupted.");
  35.       }
  36.       System.out.println("Main thread exiting.");
  37.    }
  38. }

Some other thread concepts you need to know for advanced multithreading programming

  • Thread states (Life cycle of a thread)
  • Thread synchronization
Multiple threads running within a program may share the same resources. Therefore, there is a possibility that more than one thread can access the same object at the same time. Without taking appropriate care this could lead to what is known as a synchronization problem.
  • Interrupting threads (Thread Control: Suspend, Stop and Resume)
The life of a thread ends when its run method finishes execution. Sometimes, you may want to terminate a thread from another thread.
  • Inter-thread Communication

Class Exercises

  • What are the two ways of creating threads in Java?
  • Is extending the Thread class in your Java programs always possible?
  • For a multithreaded program, you will start a thread running by invoking the __________ method on your Thread object which will in turn invoke the _________ method.
  • Compile and Run the first example. Write down the output of the program.
  • Compile and Run the second example. Write down the output of the program.
  • Study the first example. What will happen if the statement at line#28 is moved to between line#36 and line#37?
  • Write a Java multithreading program to simulate a horse racing game.
The following code segment may be useful to you.
     public void run() {
        try {
           for(int i = 100; i > 0; i--) {
              System.out.println(horsename + "--> " + i);
              Thread.sleep((long) (Math.random() * 100));
           }
        } catch (InterruptedException e) {
           System.out.println("Child interrupted.");
        }
        System.out.println("Horse " + horsename + " finishes");
     }

Reading


Thanks for Reading

If you would rather like to have this lecture note in printed format, please click the print action link in the top right corner.

If you find any problem in this lecture note, please feel free to tell Steven via steven@findaway.hk.

Edit - History - Print - Recent Changes - Search
Page last modified on November 03, 2009, at 09:54 AM