Threads

*** need interrupt description and example****
*** need thread state diagram ***

In a single thread only one piece of work can be actioned at a time, with multiple threads multiple tasks can be actioned at the same time. A thread means two different things:

An instance of Thread is just a object, it can have variables and methods and lives and dies on the heap, a thread of execution is an individual process (a lightweight process) that has it's own call stack. There is always at least one thread ( the one that calls main( ) ) which is called the main thread. Different JVM's treat threads differently, there is no guarantee that code on one system will work the same on another.

Just as we start from main( ) in an application program we always start from run( ) in a thread instance, you can define and instantiate a thread in one of two ways

In the real world you are more than likely to implement the runnable interface than extend Thread, however extending the Thread class is easier but is considered bad practice because subclassing should be reserved for classes that extend an existing classes, because they're a more specialized version of the more general superclass, so you should only extend the Thread class if you have a more specialized version of the Thread class.

defining a Thread using the Thread class

class myThread extends Thread {
   public void run() {                                  // need to override the run method
      System.out.println("This is my thread running");
   }
}

Note: problem with this is that you now cannot extend anything else

defining a Thread using the Runnable interface

class myRunnable implements Runnable {
   public void run() {                                  // need to override Runnable's run method
       System.out.println("This is my thread running");
   }
}

Note: Because Runnable is an interface you can still extend if you so wish

Now you need to instantiate your thread

instantiate a Thread using the Thread class myThread t = myThread();
instantiate a Thread using the Runable interface myRunnable r = myRunnable();      // This creates a runnable job, now we need a thread to run it

Thread t1 = new Thread(r);         // This is the thread that will run our runnable job
Thread t2 = new Thread(r);         // We can have multiple threads running the same job
Thread t3 = new Thread(r);         

There are multiple Thread constructors

Now that we have a Thread with a run() method, the Thread is said to be in the new state (see thread states below) , at this point the Thread is not considered to be alive. You can test to see if a thread is alive by calling the isalive() method on the thread instance.

To get the thread started (create a new call stack, etc) you call the threads start( ) method which in turns calls the run( ) method

Starting a Thread of execution t.start();
Checking a thread t see if its alive System.out.println("is Thread alive? : " + t.isAlive() );

When you call start on the thread the following happens

Make sure that you call start() to start the thread of execution and not run() as the run() method will be treated just like any normal method.

calling run()

Runnable r = new Runnable();
r.run();                                // treats the run as a normally method, and no thread is run


note: the run method will execute in the current already running thread, probably not what you wanted to do

A complete example follows

Complete example

public class TestThread {
   public static void main(String [] args) {
      myRunnable r = new myRunnable();

      Thread t1 = new Thread();
      Thread t2 = new Thread();

      t1.setName("Thread One");
      t2.setName("Thread Two");

      t1.start();
      t2.start();

      System.out.println("Mains Thread: " + Thread.currentThread().getName());
   }
}

class myRunnable implements Runnable {
   public void run() {
         for ( int i = 1; i < 4; i++)
            System.out.println("Thread: " + Thread.currentThread().getName());
   }
}

Note: Make sure you understand that the running order is not guaranteed, you can run this program multiple times and you may get different results each time.

We need to know a couple of these here before we gone on, when a thread has finished, the stack for that thread dissolves and the thread is considered dead. Once a Thread has finished executing, it cannot be restarted (you get a IllegalThreadStateException).

The Thread Scheduler

It is up to the JVM to decide which thread gets CPU time (although most JVM's map Java threads directly to native threads on the underlying O/S), as long as the thread is in a runnable state. The JVM will pick any thread in a runnable state so there is no guarantee which one the JVM will choose. Although we cannot get the JVM to pick a particular thread we can try and influence it a bit. However it's job is to keep the highest priority thread on the processor.

Some Java platforms support timeslicing and others may not, without timeslicing threads of equal priority run to completion before their peers get a chance to execute, with timeslicing, each thread receives a brief burst of processor time called a quantum during which that thread can execute. At the completion of the quantum, even if the thread has not finished executing, the processor is taking away from that thread and given to the next thread of equal priority if one is available.

Some of the methods in the Thread class can help the JVM to pick a particular over another thread but this is no means guaranteed

sleep(long millis) causes the current thread to sleep for the specified number of milliseconds
yield() causes the currently executing thread to temporarily pause and allow other threads to execute
join() waits for the thread to die
setPriority(int newPriority) changes the priority of the thread

Every class in Java inherits the following three thread related methods

public final void wait() causes the thread to wait until another thread invokes notify() or notifyall()
public final void notify() Wakes up a thread that is waiting on this objects monitor
public final void notifyall() wakes up all threads that are waiting on this objects monitor

Thread States

A thread can be in one of five possible states

New This is the state the thread is in after instantiated but the start() method has not been invoked on the thread.
Runnable This is the state a thread is in when it eligible to run, but the scheduler has not selected it yet, the start() method has been invoked.
Running This is where the action takes place, the JVM has selected the thread to run on the CPU, it may have a limited time and may not complete the whole of the run method, it's all up to the JVM to how much time it gets. How ever we can influence it by using the methods above: sleep, yield, join and setPriority
Waiting/Blocked/Sleeping A thread may be blocked waiting for I/O or another objects lock and rather let the thread sit on the CPU doing nothing, it is sent back to a runnable state and another thread will be allowed CPU time.
Dead When the run() method has completed for a running thread, the thread is said to be dead, you cannot restart a thread period (you will get a runtime error if you try).

******************thread state diagram*********************

Preventing Thread Execution

Sometimes you may want to slow a thread down, you can force the thread to sleep before it goes back into the runnable state after it has been exectuing. the sleep() method is a static method of the Thread Class, that you can use in your code to slow down a thread.

You pass the number of millseconds that you want the thread to sleep for, just remember that you have no control how long the thread will be on the cpu but onces it is off the cpu (now in runnable state) the thread will sleep a minimum of the number of seconds specified plus what it takes to get back on the cpu.

sleep() method

public class TestThread {
   public static void main(String [] args) {
      myRunnable r = new myRunnable();

      Thread t1 = new Thread();
      Thread t2 = new Thread();

      t1.setName("Thread One");
      t2.setName("Thread Two");

      t1.start();
      t2.start();

      // because sleep() can throw a checked InterruptedException it must be in a try-catch block
      //
       try {
             t1.sleep(10000);                   // put the thread to sleep for 10 seconds
       } catch (InterruptedException) { }
   }
}

class myRunnable implements Runnable {
   public void run() {
         for ( int i = 1; i < 100; i++)
            System.out.println("Thread: " + Thread.currentThread().getName());
   }
}

Thread priorities range from 1-10 (10 being the highest), if a thread enters the runnable state and it has a higher priority than any other threads in the pool and higher than the currently running thread, the lower priority thread will be put back into a runnable state and the higher priority thread will get access to the cpu, again this is not guaranteed, use it to improve the efficiency of your program but don't depend on it. Becareful at keeping a particular thread at low priority as it may be starved of cpu time.

If two threads are of equal priority then the JVM will decide what should run on the cpu and what should'nt and as the JVM has a mind of its own then there are no guarantees which one will run.

setting a threads priority

myRunnable r = new myRunnable();
Thread t = new Thread(r);
t.setPriority(8);
t.start();

Note: the default priority is 5

setting a threads priority using constants

myRunnable r = new myRunnable();
Thread t = new Thread(r);
t.setPriority(Thread.MAX_PRIORITY);
t.start();

Note: there are three constants that you can use
Thread.MIN_PRIORITY
Thread.NORM_PRIORITY
Thread.MAX_PRIORITY

You can use the yield() method to make a already running thread head back into a runnable state, however there are no guarantees that the JVM won't pick the same thread to go back on the cpu again.

The join() method lets one thread join "on to the end" of another thread, if you have thread B that can't do its work until another thread A has completed its work, then you want thread B to "join" thread A. This means thread B will not become runnable until thread A is in the dead state.

So there are three ways that a thread could leave the running state

A call to sleep() guaranteed to cause the current thread to stop executing for at least the specified sleep duration.
A call to yield() Not guaranteed to do much of anything, althrough it will typically cause the thread to move back to a runnable state.
A call to join() guaranteed to cause the current thread to stop executing until the thread it joins with completes.

Synchronizing Code

Take the classic banking problem were two people access the account at the same time to with draw funds, if an account has £100 in it and both people draw £100 each at the same time, if unchecked both could get £100 (£200 in total), the account will now be overdrawn by -£100 which is not what the people wanted to happen (probably have to pay extra for being overdrawn). We must guarantee that the two steps of the withdrawal - checking the balance and making the withdrawal are never split apart, they must be performed as one operation, even if the thread falls asleep in between the steps, this is called a "atomic operation" which means that the thread must complete its operation before any other thread can act on the same data.

You cannot guarantee that a single thread will stay running throughout the entire atomic operation, but you can guarantee that even if the thread running the atomic operation moves in and out of state, no other thread will be able to act on the same data (takes it's locks with it).

To protect the data you must do two things:

What you are doing here is protecting the method that accesses the private variable, you do this by using the keyword synchronized.

synchronized method private synchronized void makeWithDrawal( int amount) { .... }

Note: the synchronized keyword guarantees that no other thread can enter the method until the first thread has completed.
synchronized code block synchronized(this) { ... }

The way synchronization works is by using locks, every object in Java has a built-in lock that only comes into play when the object has synchronized method code. Since there is only one lock per object, if one thread has picked up the lock (known as obtaining the lock) no other thread can enter the synchronized code until the lock is released.

The key points to remember are

Thread Deadlock

A thread deadlock is when two threads block each other, waiting for each others resource, neither can run until the other releases its reource, kind of chicken and egg problem. An example of a deadlock code is below

Deadlock code

public class DeadLock {
   private static class Resource {
      public int value;
   }
   private Resource resourceA = new Resource();
   private Resource resourceB = new Resource();

   public int read() {
      synchronized(resourceA) {   // May deadlock here
         synchronized(resourceB) {
            return resourceB.value + resourceA.value;
         }
      }
   }

   public void write(int a, int b) {
      synchronized(resourceB) {   // May deadlock here
         synchronized(resourceA) {
            resourceA.value = a;
            resourceB.value = b;
         }
      }
   }
}

Note: there is a potential risk that this code will deadlock

Below is a table that explains when a lock is released or when it is not

Give up locks Keep Locks

Class defining the method

wait() notify()

(Although the thread will probably exit the synchronized code shortly after this call, and thus giving up its locks)
java.lang.Object
  join() java.lang.Thread
  sleep() java.lang.Thread
  yield() java.lang.Thread

Thread Interaction

Threads communicate their lock status through three methods

All three methods must be called from a synchronized method or block. A thread cannot invoke a wait or notify method on an object unless it owns that object's lock. Every object inheriates the three methods from the Object class.

wait() causes the current thread to wait until another thread invokes the notify() or notifyall() method for this object
notify() wakes up a single thread that is waiting on this object's monitor
notifyAll() wakes up all threads that are waiting on this object's monitor

An example using the wait() and notify() methods, every object can have a list of threads that are waiting for a signal from the object, again there is no order who on the list gets access when notify is called, any one could be choosen (no guarantee order).

Example

class ThreadA {
   public static void main(String [] args) {
      ThreadB b = new ThreadB();
      b.start();

      synchronized(b) {
         try {
            System.out.println("Waiting for b to complete");
            b.wait();
         } catch (InterruptedException e) {}
      }
      System.out.println("Total is: " + b.total);
   }
}

class ThreadB extends Thread {
   int total;

   public void run() {
      synchronized(this) {
         for ( int i = 0; i < 100; i++) {
            total += i;
         }
         notify();
         // notifyAll();           // if you think more than one thread will be waiting
      }
   }
}

Note: One thing i noticed is that ThreadA must be in the waiting state before ThreadB issues it's notify otherwise ThreadA stays in a waiting state for ever and ever, unless you specify a time with the wait method i.e wait(1500)

One further note is that the locks are only released when the synchronized block is finished not when notify is called.

The difference between notify() and notifyAll() is that when you have a list of threads waiting on the lock notify() will only notify one thread which one it is is up to the JVM, notifyall() will notify all waiting threads. So if you ever have a number of threads waiting for a lock then it is best to use notifyAll()

Key Thread Methods

Below is a table which lists the classes and the assoicated methods regarding Threads

Class Object Class Thread Interface Runnable
wait() start() run()

notify()

yield()  
notifyAll() sleep()  
  join()  

Daemon Threads

A daemon thread is a tread that runs for the benefit of other threads, they run in the background. Unlike normal threads, daemon threads do not prevent a program terminating. The garbage collector is a daemon thread.

Create a daemon thread

class myRunnable implements Runnable {
   public void run() {                                  // need to override Runnable's run method
       System.out.println("This is my thread running");
   }
}

myRunnable r = myRunnable();      // This creates a runnable job, now we need a thread to run it

Thread t1 = new Thread(r);        // This is the thread that will run our runnable job

t1.setDaemon( true );             // set a thread to be a daemon thread, must be set before calling                                   // start()

t1.start();

Thread Groups

Sometimes it is useful to identify various threads as belonging to a thread group, class ThreadGroup contains methods for creating and manipulating thread groups. You would useful for example to interrupt all threads in the group, set the priority of all threads in the group, you can also have groups within groups.

There are two constructors in the ThreadGroup class

Example