# Threads

# Basic Idea

- Execute more than one piece of code at the "same time".
- If more than one CPU, true concurrency is possible.
- If only one CPU, use time slicing.
  - Rotates CPU among threads / processes.
  - Gives appearance of simutaneous execution.
  - Very advantageous in several situations.
  - Cost of switching is important.
  - Doesn't improve CPU-bound task.

# Threads vs Processes

### Multiple processes / tasks

- Separate programs.
- Separate address spaces.
- High switching overhead
- Costly interprocess communication.

### Threads

- Within one program.
- Shared address space
  - May use same hardware cache
  - May use same virtual memory.
  - Shared heap.
  - Separate stack for each thread.
- Lower switching overhead than processes.
- Easy communication with other threads.

# Cooperative vs Pre-emptive

### Cooperative multithreading

- A thread decides when to give up the CPU.
- It can call `yield()` to temporarily give it up.
- Older systems: Windows 3.1, Mac OS ?
- One thread can hog the whole CPU.
- More efficient for some applications because fewer switches. Solaris "green threads".

### Pre-emptive

- OS allocates time slice to a thread.
- At the end of the time slice, or when blocked, other higher or equal priority threads are given a time-slice.
- Used on most systems.

### Operating system may choose

- Hard to write really portable multi-threaded applications.

# Example - Long action

### Problem

The user presses a button on the GUI interface that starts a long action. The single GUI thread is now in use, so the GUI interface becomes completely unresponsive until the action is completed.

### Solution

For long actions, start a separate thread so that the GUI thread may continue to operate the interface.

# Example - Slow IO

### Problem

IO is relatively slow. Let's say you're writing a browser. It reads a web page that has a lot of links to images. If you get the images sequentially, the program will spend most of its time waiting for network IO operations to complete.

### Solution

Start a separate thread for each image that must be loaded. The IO wait time is therefore reduced to the longest wait, not the sum of all waits.

# Example - Animation

### Problem

You want to show an animated image, but also continue regular processing. Every so many milliseconds you need to draw a new image. How can you do this while you are doing some other computation?

### Solution

Start a separate thread for the animation that starts up at regular intervals. The javax.swing.Timer class is a class that helps you do this.

# Thread Life Cycle States

- New - Created, but no one has requested it to start.
- Ready - It's in a queue ready to run and is waiting for the CPU.
- Running - It's currently running.
- Waiting - It's waiting for something. When finished waiting, goes to ready queue.
  - Waiting. Someone needs to tell it to go (`notify()` / `notifyAll()`)
  - Sleeping. Waiting for a time interval to expire.
  - Blocked by IO. Completion of IO will put it in the ready queue again.
  - Blocked by synchonization. Someone else has locked object that is needed.

# Thread Life Cycle Transition State Diagram

[ INSERT DIAGRAM HERE ]

# Thread Scheduling

- Every thread has a priority.
- The OS may not support this many levels.
- The OS scheduler chooses highest priority Ready thread to run.
- It's possible for low priority threads to "starve".

# Thread class and Runnable Interface

- Runnable
  - Must define the `run()` method.
  - Implement Runnable if you are only going to `start()` a tread.
- Thread class
  - Implements Runnable, so must define run()
  - Has other methods.

# Synchronization

- Every object has a monitor.
- Only one thread can lock an object's monitor at one time.
- Calling a synchronized instance method locks that object's monitor.
  - Other calls block when they call that synchronized method.
  - When method returns, lock is freed.
  - Scheduler may then run one of the blocked threads.
- Deadlocks are largely prevented, but will throw exception if detected.
- Blocks may also be synchronized.

# Data Structures and Synchronization

- Before Java 1.2
  - All data structures synchronized, eg, Vector
  - There is overhead in entering synchronized methods.
- Java 1.2 Collections
  - Newer data structures are NOT synchronized by default.
  - Can create a synchronized wrapper if needed.
- Java 5
  - Some concurrent data structures are added. These are carefully coded so they may be used by more than one thread without synchronization and without producing bad results.
  - It can be difficult to verify that code can be executed concurrently.
  - Remember that each thread has its own stack.

# Daemon Threads

- Threads that are only uses for services should be marked as Daemon threads.
- Example: A timer thread.
- `th.setDaemon(true);`
- If only daemon-threads remain, the program is terminated.

# Thread Methods

- `Thread.currentThread()` - Returns current thread.
- `Thread.sleep(millis)` - Sleeps current thread # milliseconds.
- `th.start()` - Starts thread th.
- `th.interrupt()` - Interrupts th.
  - If th is blocked, th throws InterruptedException.
  - Otherwise a flag is set that must be tested by th.
- `th.isInterrupted()` - True if interrupted. Eg,
  - `if (Thread.currentThread().isInterrupted()) ...`
- `th.join()` - Waits for th to "die".
- `th.yield()` - Voluntarily allows other threads to execute.

# Thread Example

- Create a thread. Do everything inside run() method.

      Thread busyBee = new Thread() {
          public void run() {
              doAllThatWork();
          }
      }

- Start the thread where appropriate. The start() method creates a new call stack for this thread and then calls the run() method.

      busyBee.start();

- If you call run() yourself, it will just run it in your thread.

# Object Methods for Threads

- `obj.wait()` - Current thread waits until object unlocked by `notify()` call.
- `obj.notify()` - Awakens arbitrary thread "waiting" for this object. Can only be called if current thread owns the lock on this object (eg, in a synchronized method). Arbitrary thread is still blocked until current thread releases lock.
- `obj.notifyAll()` - Awakens all threads "waiting" for this object..

# Timers

- javax.swing.Timer
- java.util.Timer
- [TODO: Insert example here]

# GUI and Threads

- New GUI event-dispatching thread started by `setVisible()`.
- Main thread can terminate after starting GUI.
- Listeners are called on the GUI thread.
- GUI is paralyzed if listeners take too long!

# Separate Thread for Long Actions

- Start another "worker" thread for long processes.
- If response is still too slow, might have to lower priority of worker thread.
- Swing is not thread safe. After worker thread terminates, how is it going to update the GUI?
- Solution: Add a Runnable object to the GUI event queue (FIFO).
  `SwingUtilities.invokeLater(Runnable)`
- The GUI thread will execute it when there is no conflict.

# GUI Listener Example

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
    Thread   m_busyBee     = new WorkerBee();
    Runnable m_showResults = new ResultsDisplayer();
    JButton  m_gatherBtn   = new JButton("Gather Honey");
             m_gatherBtn.addActionListener(new BeeListener());
    . . .
    class ResultsDisplayer implements Runnable {
        public void run() {
            showWorkResults();
        }
    }

    class WorkerBee extends Thread {
        public void run() {
            gatherHoney();
            SwingUtilities.invokeLater(m_showResults);
        }
    }

    class BeeListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            disableControlsEnableCancel();
            m_busyBee.start();
        }
    }

# Updates to make

- Analogy with database transactions.
- Give an example of simultaneous account updates, eg, as in Horstmann.
- What happens to other threads when System.exit() is called?
- Reference to Doug Lea's book.

# End