Imprint | Privacy Policy

Threads

(Usage hints for this presentation)

IT Systems, Summer Term 2024
Dr. Jens Lechtenbörger (License Information)

1. Introduction

1.1. Core Questions

  • What exactly are threads?
    • Why and for what are they used?
    • How does switching between threads work?
    • How are they created in Java?
    • What impact does blocking or non-blocking I/O have on the use of threads?

(Based on Chapter 2 of (Hailperin 2019))

1.2. Learning Objectives

  • Explain thread concept, thread switching, and multitasking
    • Including states (after upcoming presentation)
    • Explain distinctions between threads and processes
    • Explain advantages of a multithreaded organization in structuring applications and in performance
  • Inspect threads on your system
  • Create threads in Java
  • Discuss differences between and use cases for blocking and non-blocking I/O

1.3. Retrieval practice

1.3.1. Informatik 1

What are interfaces and classes in Java, what is “this”?

If you are not certain, consult a textbook; these self-check questions and preceding tutorials may help:

1.3.2. Recall: Stack

  • Stack = Classical data structure (abstract data type)
    • LIFO (last in, first out) principle
    • See Appendix A in (Hailperin 2019) if necessary
  • Two elementary operations
    • Stack.Push(o): place object o on top of Stack
    • Stack.Pop(): remove object from top of Stack and return it
  • Supported in machine language of most processors (not in Hack, though)

1.3.3. Drawing on Stack

What's the stack?

What's the stack?

Figure © 2016 Julia Evans, all rights reserved; from julia's drawings. Displayed here with personal permission.

1.3.4. Previously on OS …

1.4. Terminology

1.4.1. Parallelism

  • Parallelism = simultaneous execution
    • E.g., multi-core
    • Potential speedup for computations!
  • Note
    • Processors contain more and more cores
    • Individual cores do not become much faster any longer
    • Consequence: Need parallel programming to take advantage of current hardware

1.4.2. Concurrency

  • Concurrency is more general term than parallelism

    • Concurrency includes
      • Parallel threads (on multiple CPU cores)

        • (Executing different code in general)
      • Interleaved threads (taking turns on single CPU core)

Agenda

2. Threads

2.1. Threads and Programs

  • Program vs thread

    • Program contains instructions to be executed on CPU
    • OS schedules execution of threads

      • By default, program execution starts with one thread
        • Thread = unit of OS scheduling = independent sequence of computational steps
      • Programmer determines how many threads are created

    • Simple programs are single-threaded
    • More complex programs can be multi-threaded
      • Multiple independent sequences of computational steps
        • E.g., an online game: different threads for game AI, GUI events, network handling
      • Multi-core CPUs can execute multiple threads in parallel

2.2. Thread Creation and Termination

  • Different OSes and different languages provide different APIs to manage threads

    • Thread creation

    • Thread termination
      • API-specific functions to end/destroy threads
      • Implicit termination when “last” instruction ends
        • E.g., in Java when methods main() (for main thread) or run() (for other threads) end (if at all)

2.3. Thread Classification

  • I/O bound vs CPU bound

    • I/O bound

      • Threads spending most time submitting and waiting for I/O requests
      • Run only for short periods of time
        • Until next I/O operation
        • E.g., virus scanner, network server for web or chat
    • CPU bound

2.4. Reasons for Threads

  • Resource utilization

    • Keep most of the hardware resources busy most of the time, e.g.:
      • While one thread is idle or blocked (e.g., waiting for external events such as user interaction, disk, or network I/O), allow other threads to continue
      • Parallelism: Utilize multiple CPU cores
        • Different threads on different cores
  • Responsiveness

    • Use separate threads to react quickly to external events
      • Think of game AI vs GUI
      • Other example on later slide: Web server
  • More modular design

2.5. Interleaved Execution Example

Interleaved execution example” by Jens Lechtenbörger under CC BY-SA 4.0; SVG image refers to converted and cut parts of Figure 2.6 of a book by Max Hailperin under CC BY-SA 3.0. From GitLab

3. Thread Switching

3.1. Thread Switching for Multitasking

  • OS schedules threads (details in later lecture)
    • (Similar to machine scheduling for industrial production, which you may know from operations management)
    • Recall multitasking
      • OS may use time-slicing to schedule threads for short intervals
      • Illusion of parallelism on single CPU core
  • Scheduling involves context switches
    • (Recall introduction and interrupts; now, as thread switch)
    • Remove current thread from CPU
      • Remember computation state (in TCB: program counter, register contents, stack, …)
    • Dispatch next thread to CPU
      • Restore computation state

3.2. Thread Control Blocks (TCBs)

  • All threads share the same CPU registers
    • Obviously, register values need to be saved somewhere to avoid incorrect results when switching threads
    • Also, each thread has its own
      • program counter; where to execute next machine instruction
      • stack; current position given by stack pointer (SP)
    • Besides: priority, scheduling information, blocking events (if any)
  • OS uses block of memory for housekeeping, called thread control block (TCB)
    • One for each thread
      • Storing register contents, stack pointer, program counter, …

4. Java Threads

4.1. Threads in Java

  • Threads are created from instances of classes implementing the Runnable interface
    1. Implement run() method
    2. Create new Thread instance from Runnable instance
    3. Invoke start() method on Thread instance

4.2. Java Thread Example

public class Simpler2Threads { // Based on Fig. 2.3 of [Hai17]
  // "Simplified" by removing anonymous class.
  public static void main(String args[]){
    Thread childThread = new Thread(new MyThread());
    childThread.start();
    sleep(5000);
    System.out.println("Parent is done sleeping 5 seconds.");}

  static void sleep(int milliseconds){
    // Sleep milliseconds (blocked/removed from CPU).
    try{ Thread.sleep(milliseconds); } catch(InterruptedException e){
      // ignore this exception; it won't happen anyhow
    }}}

class MyThread implements Runnable {
  public void run(){
    Simpler2Threads.sleep(3000);
    System.out.println("Child is done sleeping 3 seconds.");
  }}

4.3. Self-Study Task: CPU Usage

Aspect of this task are available for self-study in Learnweb.

  • Compile and run source code of Simpler2Threads
    • Explain its output. Maybe ask in Learnweb.
    • Maybe try out debugger, e.g., jdb with OpenJDK tools:
      • jdb Simpler2Threads
      • help
      • stop in Simpler2Threads.main
      • run
      • threads
      • stop in MyThread.run
      • step
      • threads

5. Server Models

  • Web server “talks” HTTP with browsers

    • Simplified
      • Lots of browsers ask per GET method for various web page parts
      • Server responds with HTML files and other resources

    Figure 2.5 of cite:Hai19

    Figure 2.5 of cite:Hai19” by Max Hailperin under CC BY-SA 3.0; converted from GitHub

5.1. Server Models with Blocking I/O: Multi-Threaded

  • One thread (or process) per client connection
  • Parallel processing of client connections
    • No idle time for I/O (switch to different client)
    • Limited scalability (thousands or millions of clients?)
      • Creation of threads causes overhead
        • Each thread allocates resources
      • OS needs to identify “correct” thread for incoming data
  • Worker Thread Pool as compromise

5.2. Server Models with Non-Blocking I/O

  • Single thread
    • Event loop, event-driven programming
    • E.g., web servers such as lighttpd, nginx
  • Finite automaton to keep track of state per client
    • State of automaton records state of interaction
    • Complex code
  • Avoids overhead of context switches

5.3. Worker Thread Pool

  • Upon program start: Create set of worker threads
  • Client requests received by dispatcher thread
    • Requests recorded in data structure with work items
  • Idle worker threads process requests
  • Note
    • Re-use of worker threads
    • Limited resource usage
    • How to tune for load?
      • Dispatcher may be bottleneck
      • If more client requests than worker threads, then potentially long delays

5.3.1. Aside: Virtual Threads in Java

  • Beyond class topics
  • Java 19 introduced virtual threads in preview API
    • See JEP 436 or blog post for details
    • Updates for Java 21 in JEP 444
    • Overhead reduced to enable thread per client model with blocking I/O
      • Map large number of virtual threads to pool of small number of OS threads
      • When virtual thread blocks on I/O, Java runtime performs non-blocking OS call and
        • suspends virtual thread until it can be resumed later and
        • executes different virtual thread on same OS thread

6. Conclusions

6.1. Summary

  • Threads represent individual instruction execution sequences
  • Multithreading improves
    • Resource utilization
    • Responsiveness
    • Modular design in presence of concurrency
  • Multithreading with housekeeping by OS
    • Thread switching with overhead
  • Design choices: I/O blocking or not, servers with multiple threads or not

Bibliography

Barroso, Luiz, Mike Marty, David Patterson, and Parthasarathy Ranganathan. 2017. “Attack of the Killer Microseconds.” Cacm 60 (4): 48–54. https://dl.acm.org/citation.cfm?id=3015146.
Hailperin, Max. 2019. Operating Systems and Middleware – Supporting Controlled Interaction. revised edition 1.3.1. https://gustavus.edu/mcs/max/os-book/.

License Information

Source files are available on GitLab (check out embedded submodules) under free licenses. Icons of custom controls are by @fontawesome, released under CC BY 4.0.

Except where otherwise noted, the work “Threads”, © 2017-2024 Jens Lechtenbörger, is published under the Creative Commons license CC BY-SA 4.0.