Multi-threading

Starting threads

  • start() starts the thread; Java will call the thread's run() method.
  • The thread will run until run() exits, or stop() is called.
Thread t = new Thread();
t.start();

Stopping threads

  • The thread becomes dead, and cannot be used again.
myThread.stop();

Suspending threads

  • Call the thread's suspend() method; restart the thread by calling resume()
  • Call the thread's sleep() method; the thread will restart automatically.
  • The thread can call its own wait() method; restart the thread by calling notify() or notifyAll()

Splicing threads together

  • Joins the specified thread to the current thread.
myThread.join();

Synchronizing blocks of code

synchronized (myClass) { /* Block of code */ }
synchronized (myObject) { /* Block of code */ }
  • Synchronizes a section of code in a method.
  • Can lock either the class or the object.

Synchronizing methods

public synchronized void myFunction() {...}                        
  • Entering a synchronized static method locks the class.
  • Entering a synchronized instance method locks the object.
  • A monitor is associated with each class and each object, to lock the class or object.
  • The monitor is exited when then method is exited or when the thread calls wait().

Volatile variables

  • The compiler won't optimize calculations involving a non-changing variable in a loop (like x * x, preconditioned before the loop, and resulting value used in the loop).
  • Use when a separate thread may affect the variable while the loop is running.
volatile int myVariable;

Implementing Runnable

  • An alternative to extending a thread and providing it's own run() method.  Can use an existing class in which the thread will run.
class MyChild extends MyParent implements Runnable {
public void run() {...};
public void MyChild() {
Thread t = new Thread();
t.target = this;
t.start(); // starts running MyChild::run()

Thread t2 = new Thread(this, "MyChild");
t2.start(); // starts running MyChild::run()
}
}

Thread priority

  • The highest-priority thread is always the one that runs.  If there is more than one thread with that priority, they take turns running.
  • Preemptive multitasking: if a lower-priority thread becomes a higher-priority thread and now has the highest priority, the thread that was running will be suspended, and the higher-priority thread will start executing immediately.
  • The default priority for a thread is the priority of the thread that created it.
  • Can set a thread's priority, from MIN_PRIORITY to MAX_PRIORITY

Thread states

  • New thread - has been created, but start() has not been called yet.
  • Runnable - is running, or is about to run.
  • Not runnable - is suspended.
  • Dead - Waiting for garbage collection.  Can't be used again.

Deadlock

  • 2 threads are waiting for a resource to be freed that the other is using, for example.
  • Avoid calling one synchronized method from another whenever possible.
  • Use a monitor for the shortest time possible.