Alan Kaminsky Department of Computer Science Rochester Institute of Technology 4486 + 2220 = 6706
Home Page
Operating Systems I 4003-440-02 Winter Quarter 2012
Course Page

4003-440-02 Operating Systems I
Module 3. Thread Programming -- Lecture Notes

Prof. Alan Kaminsky -- Winter Quarter 2012
Rochester Institute of Technology -- Department of Computer Science


Introduction

  • Reasons for writing a multi-threaded program
    • To utilize multiple hardware processors (parallel programming)
    • To keep executing other threads when one thread has to block
    • To implement a simpler algorithm
       
  • Principal Java platform classes related to thread programming
     
    • Package java.lang
      • Class Thread
      • Interface Runnable
         
    • Package java.util.concurrent (JDK 1.5)
      • Interface Callable<V>
      • Interface Future<V>
      • Interface ExecutorService
      • Class Executors
         
  • Additional Java platform classes related to thread programming
     
    • Package java.lang
      • Class ThreadGroup
      • Class ThreadLocal<T>
      • Class InheritableThreadLocal<T>


A Sequential Program

  • Class UC1 is the main program for the URL Counter Version 1. It counts lines, words, and bytes in the URLs given on the command line. It is a sequential (single-threaded) program.
     
    Usage: java edu.rit.os1.UC1 url . . .
     
  • Package edu.rit.os1
  • Running time measurements


Thread Creation, Alternative 1

  • Problem: Program UC1 spends a lot of time doing nothing, waiting for URL data to download
     
  • Solution: Do each URL in its own separate thread
     
  • Class UC2 is the main program for the URL Counter Version 2. It counts lines, words, and bytes in the URLs given on the command line. It is a multi-threaded program where each URL counter object is a subclass of class Thread.
     
    Usage: java edu.rit.os1.UC2 url . . .
     
  • Package edu.rit.os1
  • Pattern
    • Write a subclass of class Thread, override the run() method
    • Create an instance of the Thread subclass
    • Call the thread's start() method
    • Original thread returns from start() and continues executing
    • New thread executes the thread's run() method
    • When the run() method returns, the new thread terminates
       
  • "synchronized (System.out) { ... }" in class URLCounterThread
     
  • Running time measurements


Waiting For Thread Termination

  • Problem: Program UC2 prints its running time before any of the threads execute!
     
  • Solution: The main program must wait for all the threads to terminate before printing the running time
     
  • Class UC3 is the main program for the URL Counter Version 3. It counts lines, words, and bytes in the URLs given on the command line. It is a multi-threaded program where each URL counter object is a subclass of class Thread. Before returning, the main program waits for all the threads to terminate.
     
    Usage: java edu.rit.os1.UC3 url . . .
     
  • Package edu.rit.os1
  • Pattern
    • To wait for a target thread to terminate, call join() on the target thread
    • join() does not return until the target thread terminates
    • The thread calling join() is blocked until the target thread terminates
       
  • Running time measurements


Thread Creation, Alternative 2

  • Class UC4 is the main program for the URL Counter Version 4. It counts lines, words, and bytes in the URLs given on the command line. It is a multi-threaded program where each URL counter object implements interface Runnable but is not a subclass of class Thread. Before returning, the main program waits for all the threads to terminate.
     
    Usage: java edu.rit.os1.UC4 url . . .
     
  • Package edu.rit.os1
  • Pattern
    • Write a class that implements interface Runnable, implement the run() method
    • Create an instance of the runnable object
    • Create an instance of class Thread, passing the runnable object to the thread constructor
    • Call the thread's start() method
    • Original thread returns from start() and continues executing
    • New thread executes the runnable object's run() method
    • When the run() method returns, the new thread terminates
       
  • Running time measurements


Thread Creation, Alternative 3

  • Problem: That's a fair rigamarole to create all the threads and wait for them all to terminate -- isn't there a simpler way?
     
  • Solution: Use a thread pool -- new in JDK 1.5
     
  • Class UC5 is the main program for the URL Counter Version 5. It counts lines, words, and bytes in the URLs given on the command line. It is a multi-threaded program where each URL counter object implements interface Runnable but is not a subclass of class Thread. The main program uses a thread pool rather than creating threads directly.
     
    Usage: java edu.rit.os1.UC5 url . . .
     
  • Package edu.rit.os1
  • Pattern
    • Write a class that implements interface Runnable, implement the run() method
    • Create an ExecutorService (thread pool) using a static method of class Executors
      • Several different kinds of thread pools are available
      • We will generally use a cached thread pool, which reuses idle threads if possible and creates new threads if necessary
    • Create an instance of the runnable object and pass it to the thread pool's execute() method
    • Original thread returns from execute() and continues executing
    • Thread pool executes the runnable object's run() method in a separate thread
    • To wait for all threads to terminate, call shutdown() followed by awaitTermination() on the thread pool
       
  • Running time measurements


Getting Results From Thread Executions

  • Problem: Suppose we want to add up the counts for all the URLs
     
  • Solution: Use futures to return results back to the main thread -- new in JDK 1.5
     
  • Class UC6 is the main program for the URL Counter Version 5. It counts lines, words, and bytes in the URLs given on the command line. It is a multi-threaded program where each URL counter object implements interface Runnable but is not a subclass of class Thread. The main program uses a thread pool rather than creating threads directly. The main program also prints the total lines, words, and bytes in all the URLs.
     
    Usage: java edu.rit.os1.UC6 url . . .
     
  • Package edu.rit.os1
  • Pattern
    • Write a class that implements interface Callable<V>, implement the call() method to return a value of type V
    • Create an ExecutorService (thread pool) using a static method of class Executors
    • Create an instance of the callable object and pass it to the thread pool's submit() method
    • submit() returns a future, an instance of interface Future<V>, to the original thread
    • Save the future somewhere
    • Thread pool executes the callable object's call() method in a separate thread and stores the call() method's return value in the corresponding future
    • To get the callable object's return value, original thread calls get() on the future -- this blocks until the return value becomes available
    • Must still call shutdown() on the thread pool
       
  • Running time measurements


Segue

  • Problem: But now we're back to processing the threads' results sequentially. Can't we accumulate the total counts concurrently also?
     
  • Problem: That's a fair rigamarole to store all the futures and then go back and process them all again -- isn't there a simpler way?
     
  • Solution: See Module 4, Thread Coordination.

Operating Systems I 4003-440-02 Winter Quarter 2012
Course Page
Alan Kaminsky Department of Computer Science Rochester Institute of Technology 4486 + 2220 = 6706
Home Page
Copyright © 2008 Alan Kaminsky. All rights reserved. Last updated 27-Aug-2008. Please send comments to ark­@­cs.rit.edu.