My other sites

Latest News

New Summer Look :)










Java Threads

 

Threads

Creating a Thread

Interface Runnable

Thread Constructors and Names

Executing Threads

InterThread Communication

Thread States

Implementing Runnable

Extending Thread

Priorities

Other Thread Methods

Synchronizing, Locks and Monitors

Synchronized Methods

Account Example

Synchronized Statements

Thread Groups

Thread Race Example

Quiz

Exercises

 

 




Threads


- An integral part of Java - From day one

- Enable concurrent execution

- A thread is a 'lightweight process'

- The VM is the process

- One run-time stack per thread

- One program counter per thread

- A process has usually several threads running

- Shared address space and memory

- Inter-thread communication

- Cheap creation and switching

- All standard libraries are 'Thread Safe'

- Cannot enter unknown states

- Can be protected from multiple simultaneous access


Creating a Thread


Two ways to create a Thread:

1. Implement Runnable & implement its run() method

2. Extend Thread & override its run() method

This is due to single inheritance in Java

Extending Thread means you cannot extend another class

The first alternative is more used


Interface Runnable


Runnable is a very simple interface, it has just one method

The Thread's start() method calls the Runnable's run() method

public interface Runnable {
public abstract void run();
}


Thread Constructors and Names

  There are four basic constructors; their arguments can be:

1. A name (String) for the Thread (default null) - Should be unique, used for debugging etc.

2. An object (Runnable) to call a run() method in - Default is this object


class ThreadExample implements Runnable {
    public ThreadExample {
      Thread t1 = new Thread();
      Thread t2 = new Thread("sun");
      Thread t3 = new Thread(this);
      Thread t4 = new Thread(this, "t4");
      String n2 = getName();
      t3.setName("t3");
    }
    public void run() { }
}


Executing Threads

run()

start()

stop()

suspend()

resume()

destroy()

isAlive()

yield()

join()

sleep(long)

interrupt()

Run it! (Runnable)

Activates the thread and calls run()

Forces the thread to stop

Temporarily halt the thread

Resume a halted thread

Equivalent to UNIX's "kill -9"

Is it running?

Let another thread run

Wait for the death of a thread

Sleep for a number of milliseconds

Interrupt sleep, wake up!


InterThread Communication

Inter-thread communication methods are declared in java.lang.Object

Each object can be associated with a monitor (a sort of thread lock)

wait()
- Suspend the thread
- Wait can also be time limited

notify()
- Unlock the first monitored thread
- (The first that called wait() within the monitor)

notifyAll()
- Unlocks all monitored threads
- Highest prioritised first

 

Thread States

 

 


Implementing Runnable

 
class MyThread implements Runnable {
  MyThread() {
  }
  public void run() {
    // Loop forever...?
  }
 public static void main(String[] args) {
  Thread mythread = new Thread(new MyThread());
     mythread.start();
     mythread.stop();
   }    
}


Extending Thread

 
class MyThread extends Thread {
  MyThread() { }
  public void run() {
     // Loop forever...
  }
  public static void main(String args[]) {
    MyThread myThread = new MyThread();
    myThread.start();
    myThread.stop();
  }    
}


Priorities


- Priority per thread

- No real-time priorities

- Initiated to the creator's priority

public class Thread implements Runnable {
  ...
  public final static int MIN_PRIORITY;  // 1
  public final static int NORM_PRIORITY; // 5
  public final static int MAX_PRIORITY;  // 10
  public final int    getPriority();
  public final void setPriority(int);
  ...
}


Other Thread Methods


currentThread()
- Returns the currently executing thread (static)

setDaemon(boolean)
- Sets a thread as daemon; the VM exits when all threads are daemons

isDaemon()
- Returns true if the thread is a daemon

 

 

Synchronizing, Locks and Monitors

  All objects may be associated with a monitor

Monitors aggregate mutually exclusive locks
- Synchronized methods
- Synchronized statements


Synchronized Methods

 

A synchronized method -> mutual exclusion (lock) per object

A synchronized static method -> mutual exclusion (lock) per class

synchronized void myObjectMethod() { }

synchronized static void myClassMethod() { }


Account Example


This is an example of synchronized methods:
public class Account {
    private double balance;

    public Acount(double initialDeposit) {
      balance = initialDeposit;
    }

    public synchronized double getBalance() {
      return balance;
    }

    public synchronized void deposit(double amount) {
      balance += amount;
    }
}


Synchronized Statements

The synchronized statement:

- mutual exclusion (lock) of data access instead of a synchronized method

- very lightweight

Syntax:
synchronized(Object) {
}


Synchronized Statements


Example (mutual exclusive lock on the variable values) :

  public static void abs(int[] values) {
    synchronized(values) {
      for (int i=0; i < values.length; i++) {
        if (values[i] < 0)
          values[i] = -values[i];
      }
    }
  }


Thread Groups

- A thread group represents a set of threads

- In addition, a thread group can also include other thread groups

- A thread may only access information about its own thread group


public Thread(ThreadGroup, Runnable);
public Thread(ThreadGroup, Runnable, String);
public Thread(ThreadGroup, String);


- The VM is one ThreadGroup while the application is another one



Thread-Race

 
import java.awt.*;
import java.awt.event.*;

public class ThreadRace extends Frame {
   public static void main(String[] args) {
       ThreadRace myThreadRace = new ThreadRace(
"ThreadRace Example"); } public ThreadRace(String s) { super(s); setBackground(Color.red); setLayout(new GridLayout(10,1,3,3)); myWindowListener mwl = new myWindowListener(); addWindowListener(mwl); for (int i=1;i<11;i++) { myPanel mp = new myPanel(i); add(mp); } pack(); setVisible(true); } } class myPanel extends Panel implements Runnable { int x=10; Thread t1=null; int priority; public myPanel(int prior) { t1 = new Thread(this); t1.setPriority(prior); priority = prior; t1.start(); } public void run() { while(true) { if (x>490) x=10; x++; try { t1.sleep(40); } catch (InterruptedException ie) { } repaint(); } //end while } public void paint(Graphics g) { g.setColor(Color.white); g.fillRect(0,0,500,50); g.setColor(Color.black); g.drawLine(10,25,490,25); g.setColor(Color.blue); g.fillOval(x,20,10,10); g.setColor(Color.red); g.drawString(String.valueOf(priority),x+2,22); } public Dimension getPreferredSize() { return (new Dimension(500,50)); } } // end class myPanel class myWindowListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } }


Quiz


1. Imagine that one thread, T1, needs to access two objects (one file for writing banking data, and a String that contains the balance). These two objects are declared Synchronized, so that no other thread can access these objects at the same time. A second thread, T2, runs in parallel with T1 and needs to access the same objects too. While T1 locks the file (but not the String), T2 manages to lock the String, but not the file. What happens next?


Exercises


1. Create a console application and create and use two threads that are printing an increasing counter. Change the threads priorities and notice the effect on the counters. Use the Thread’s sleep method if you need to slow down the printing

2. Create a simple animation on a Container which holds a Pause and a Play button. To do so you will need to control a thread that loops and calls Panel’s repaint method

3. Create a Frame and put three of the above containers. Append a list for the user to select from a range of thread priorities. Can you see any difference on your animation?