Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Java Lesson 43: Multithreading, the Thread class, and the Runnable interface

JavaFAQ Home » Java Lessons by Jon Huhtala Go to all tips in Java Lessons by Jon Huhtala


Bookmark and Share
All Java Lessons contents page | Java Lesson 1 | Java Lesson 2 | Java Lesson 3 | Java Lesson 4 | Java Lesson 5 | Java Lesson 6 | Java Lesson 7 | Java Lesson 8 | Java Lesson 9 | Java Lesson 10 | Java Lesson 11 | Java Lesson 12 | Java Lesson 13 | Java Lesson 14 | Java Lesson 15 | Java Lesson 16 | Java Lesson 17 | Java Lesson 18 | Java Lesson 19 | Java Lesson 20 | Java Lesson 21 | Java Lesson 22 | Java Lesson 23 | Java Lesson 24 | Java Lesson 25 | Java Lesson 26 | Java Lesson 27 | Java Lesson 28 | Java Lesson 29 | Java Lesson 30 | Java Lesson 31 | Java Lesson 32 | Java Lesson 33 | Java Lesson 34 | Java Lesson 35 | Java Lesson 36 | Java Lesson 37 | Java Lesson 38 | Java Lesson 39 | Java Lesson 40 | Java Lesson 41 | Java Lesson 42 | Java Lesson 43 | Java Lesson 44 | Java Lesson 45 | Java Lesson 46

Java Lesson 43 by Jon Huhtala

Multithreading, the Thread class, and the Runnable interface

Overview

In every day life, you frequently perform two or more tasks simultaneously. For example, you could be talking on the telephone while having a cup of coffee and watching television. Although you might think you are performing all three tasks at the same time, you really aren't. By quickly shifting your attention from one activity to another, you are able to complete all three tasks without actually performing any two at precisely the same time. In addition, the tasks may have different priorities. One may be given more attention (time) than another and these priorities may change.

In a similar manner, a Java program can perform two or more processes simultaneously. When it does, it is called multithreading.

Multithreading

  • Is a fundamental feature of the Java language specification. The creators of Java understood the importance of multithreading and provided easy to use features for application developers. Two of these features, the Thread class and the Runnable interface, will be covered shortly.

  • Is not the same as multiprocessing. The latter involves the use of two or more processors (CPUs). Multithreading involves the sharing of a single processor and the interleaving of CPU time as shown by the following diagram:

    CPU time

    Thread 1 xxxxxxxxxxx xxxxx
    Thread 2 xxxxxxxxxxxxxxxx xxxxxxxx xxxxxx
    Thread 3 xxxxxxx xxxxxxxxxxx

    Because there is only one processor, only one instruction can be executed at a time. In a Java program, the decision as to which thread is currently executing is determined by the JVM.

  • Is used to execute even the simplest Java program. Even if a program doesn't create its own threads, the Java Virtual Machine creates multiple threads to support the program. One thread performs the processing of the main() method. Other threads manage and monitor system resources. The garbage collector, for example, is always running as a low-priority thread.

The life of a thread

In Java, all threads are objects that are constructed, pass between several "states", and die in keeping with the following diagram:

Runnable

Blocked

New

--->

Ready <---> Running

<--->

sleeping

waiting

suspended

Dead
  1. When initially constructed, the thread is New

  2. When all resources the thread requires are available, it enters the Ready state. The thread is ready to use the CPU.

  3. When selected by the JVM for processing, the thread enters the Running state. This is the state that all threads aspire to but only one is ever running at an instant in time.

  4. When the thread requests to sleep for an interval of time, must wait for a resource (such as completion of I/O), or is suspended by the JVM, it becomes Blocked. It gives up the CPU and will return to the Ready state when the block is removed.

  5. When the thread completes its processing or is killed by the JVM, it enters the Dead state. The thread object will still exist, but will no longer be allowed to use the CPU.

The Thread class

  • Is part of the java.lang package so no import statement is required

  • Is an extension of the Object class

Object

Thread
  • Encapsulates the processing of a thread

  • Can be extended by a class that must process as a thread. All that is required is to override the inherited run() method to define the thread's processing. For example,

public class GetMad extends Thread {
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
System.out.println("DONE");
}
}

defines a class to count from 1 to 10 as a thread. For an application to create and launch the thread, all that must be coded are the statements:

GetMad t = new GetMad();
t.start();

The inherited start() method of the Thread class automatically calls the run() method to trigger the thread's processing. A program should never call the run() method directly.

Once the thread has been launched, the application can continue its own processing thread with the JVM scheduling the use of the CPU by the two threads. Here is a complete example using a static inner class:

public class App {

public static class GetMad extends Thread {
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
}
}

public static void main(String[] args) {

GetMad t = new GetMad();
t.start();
for (int i = 1; i <= 100; i++) {
System.out.println("Working");
}
}
}

When this is run, note how the output of the two threads is interleaved.

  • Has several constructors. The most frequently used is demonstrated by

Thread aThread = new Thread(threadObject);

where threadObject is the reference of an object that either extends the Thread class or implements the Runnable interface.

Using this technique, an alternative way to have constructed the thread of the previous sample would be

Thread t = new Thread(new GetMad());

  • Has a number of methods, some of which are static. The most frequently used methods are the following:

Method

Usage

destroy()

A method that may be overridden to define what is to be done when the thread is to be destroyed

getName()

Returns a String representing the thread's name

getPriority()

Returns an int from 1 to 10 that indicates the thread's priority. The highest priority is 10.

interrupt()

Interrupts the thread

isAlive()

Returns a boolean indicating if the thread is currently alive

isInterrupted()

Returns a boolean indicating if the thread is currently interrupted

run()

A method that may be overridden to define thread processing. It should never be called directly.

setName()

Sets the name of the thread to the specified String

setPriority()

Sets the priority of the thread to the specified int value (from 1 to 10)

sleep()

Causes the currently executing thread to sleep for a specified number of milliseconds. This is a static (class) method.

start()

Causes this thread to begin execution by automatically calling its run() method

yield()

Causes the currently executing thread to give up the CPU so that other threads may execute. This is a static (class) method.

Note that the stop(), suspend(), and resume() methods of the Thread class are deprecated and should be avoided. They are unsafe and may result in errors.

Consult the Java API documentation for more details.

  • Provides a scheme for prioritizing a thread. The priority of a thread is an int value in the range of 1 to 10 (where 1 is the lowest priority and 10 is the highest priority). Unless specifically set, the priority of a thread will be the same as the thread that launched it. For an application thread, the default priority is 5.

  • Provides a general mechanism for setting a timer without creating a thread object. The sleep() method can be used to delay for a specified number of milliseconds as shown by the following program:

public class App {
public static void main(String[] args) {
System.out.println("Going to sleep for 3 seconds...");
try {
Thread.sleep(3000);
}
catch (InterruptedException err) {
}
System.out.println("Now I'm awake!");
}
}

Note that sleep() is a static method (requires no object) and may throw an InterruptedException. A method that calls Thread.sleep() must either use try and catch blocks (as shown in this example) or claim the possibility of throwing the exception.

  • Provides a general mechanism to request that the current thread give up the CPU (yield) to a thread of equal or higher priority that is in the ready state. If no other thread is ready, the JVM restores the yielding task to the running state. To make the current thread yield code

Thread.yield();

Note that yield() is a static method (requires no object) and throws no exceptions. It is a good practice for long-running threads to periodically yield and allow other threads the opportunity to use the CPU.

  • Can be used to instantiate any number of threads. For example, the following application launches several threads that display messages at different time intervals. The main application thread automatically destroys the sub-threads after 20 seconds.

public class App {

// This inner class encapsulates the processing of an Alarm thread
// that will display a message at a specified time interval.

public static class Alarm extends Thread {

// Instance variables.

private int delayInSeconds;
private int count;
private boolean isAlive;

// This method constructs an Alarm thread. It receives the time
// interval in seconds, sets the count to zero, and indicates that
// the thread is alive.

public Alarm(int seconds) {
delayInSeconds = seconds;
count = 0;
isAlive = true;
}

// This method defines thread processing. The thread will loop
// while alive to display a message at the time interval.

public void run() {
while (isAlive) {
try {
Thread.sleep(delayInSeconds * 1000);
}
catch (InterruptedException err) {
}
count += delayInSeconds;
System.out.println(getName() + ": " + count);
}
}

// This method can be called to destroy the thread.

public void destroy() {
isAlive = false;
}
}

// This is the starting point for application processing.

public static void main(String[] args) {

// Instantiate three Alarm threads with intervals of 1, 5, and 10
// seconds and start their processing.

Alarm t1 = new Alarm(1);
Alarm t2 = new Alarm(5);
Alarm t3 = new Alarm(10);
t1.start();
t2.start();
t3.start();

// Sleep for 20 seconds.

try {
Thread.sleep(20000);
}
catch (InterruptedException err) {
}

// Destroy all threads and release their resources.

t1.destroy();
t1 = null;
t2.destroy();
t2 = null;
t3.destroy();
t3 = null;
}
}

Notes:

  1. The value of the boolean variable isAlive is used to control thread processing in the run() method.

  2. The destroy() method overrides the default destroy() method inherited from the Thread class to set the value of isAlive to false (and stop thread processing).

The Runnable interface

  • Provides an alternative to extending the Thread class. If a class cannot extend Thread (due to single inheritance), it may implement the Runnable interface. This will allow an object of the class to be run as a thread.

  • Has a single required method. An implementing class must contain a run() method that defines thread processing. Its header is as follows:

public void run()

The following is a sample applet that contains an inner class for a blinking button. By extending the Button class, BlinkButton inherits normal button features. By implementing the Runnable interface and defining a run() method, it adds thread processing to make the button blink at a specified interval set by its constructor.

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

public class App extends Applet implements ActionListener {

// This inner class defines a blinking button. The Runnable
// interface is implemented and the run() method defined in
// order for an object to be run as a thread.

public class BlinkButton extends Button implements Runnable {

// For holding the blink interval in milliseconds.

int interval;

// This method constructs a blinking button object. It receives
// the button's label (which is passed through to the superclass
// constructor) and the blink speed in milliseconds (which is
// saved). It then creates and starts a thread for this object.

public BlinkButton(String label, int blinkSpeed) {
super(label);
interval = blinkSpeed;
new Thread(this).start();
}

// This method is required by the Runnable interface and defines
// thread processing.

public void run() {

// Endless loop to sleep for the specified interval then awake
// to swap the button's foreground and background colors.

while (true) {
try {
Thread.sleep(interval);
}
catch(InterruptedException err) {
}
Color oldForeground = getForeground();
setForeground(getBackground());
setBackground(oldForeground);
}
}
}

// Object references for this applet.

BlinkButton b;
TextField message;

// This method begins applet processing.

public void init() {

// Resize the applet and set its background color.

resize(300, 100);
setBackground(Color.lightGray);

// Create the blink button and add it to the applet.

b = new BlinkButton("Show message", 500);
b.setBackground(Color.black);
b.setForeground(Color.white);
b.addActionListener(this);
add(b);

// Create the message text field and add it to the applet.

message = new TextField("", 15);
message.setFont(new Font("Serif", Font.ITALIC, 24));
message.setForeground(Color.red);
message.setEditable(false);
add(message);
}

// This method is automatically called to handle the user
// clicking the blink button.

public void actionPerformed(ActionEvent e) {

// If the message is not currently displayed, display it.
// Otherwise, clear the message.

if (message.getText().length() == 0) {
message.setText("Hello world!");
b.setLabel("Clear message");
}
else {
message.setText("");
b.setLabel("Show message");
}
}
}

Looking ahead

Multithreading is a powerful tool, but can be dangerous when two or more threads share the same resource. If not properly managed, one thread can easily overlay or undo the work of another thread. This will be addressed in the next lesson.

Lab exercise for Ferris students

E-mail your answers to this assignment no later than the due date listed in the class schedule.

Review questions

  1. What will be displayed when an attempt is made to compile and execute the following program? The line numbers are for reference purposes only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class App {
public static class Inner extends Thread {
public void run(int x) {
for (int i = 0; i < 3; i++) {
System.out.println("Thread Running");
}
}
}
public static void main(String[] args) {
Inner x = new Inner();
Thread t = new Thread(x);
t.start();
}
}
  1. a compile error will occur at line 2

  2. a compile error will occur at line 3

  3. a compile error will occur at line 12

  4. the program will compile and execute to display the message "Thread Running" 3 times

  5. the program will compile and execute but nothing will be displayed

  1. What will be displayed when an attempt is made to compile and execute the following program? The line numbers are for reference purposes only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class App {
public static class Inner extends Thread {
String myName;
public Inner(String name) {
myName = name;
}
public void run() {
while (true) {
System.out.println(myName);
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new Inner("Bob"));
t1.setPriority(4);
t1.start();
Thread t2 = new Thread(new Inner("Sally"));
t2.start();
}
}
  1. a compile error will occur at line 14

  2. a compile error will occur at line 15

  3. the program will compile and execute to display "Bob" more than "Sally"

  4. the program will compile and execute to display "Sally" more than "Bob"

  5. the program will compile and execute but nothing will be displayed

  1. What will be displayed when an attempt is made to compile and execute the following program? The line numbers are for reference purposes only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class App {
public static class Inner extends Thread {
public void run() {
while (true) {
System.out.println("Sub Thread");
Thread.yield();
}
}
}
public static void main(String[] args) {
new Thread(new Inner()).start();
while(true) {
System.out.println("Main Thread");
}
}
}
  1. a compile error will occur at line 6

  2. a compile error will occur at line 11

  3. the program will compile and execute to display "SubThread" more than "MainThread"

  4. the program will compile and execute to display "MainThread" more than "SubThread"

  5. the program will compile and execute but nothing will be displayed

  1. What will be displayed when an attempt is made to compile and execute the following program? The line numbers are for reference purposes only.

1
2
3
4
5
6
7
8
public class App {
public static void main(String[] args) {
while(true) {
Thread.sleep(10);
System.out.println("Tick");
}
}
}
  1. the program will not compile

  2. the program will compile but a runtime exception will occur

  3. the program will compile and execute to display "Tick" every ten seconds

  4. the program will compile and execute to display "Tick" every ten milliseconds

  5. the program will compile and execute but nothing will be displayed


 Printer Friendly Page  Printer Friendly Page
 Send to a Friend  Send to a Friend

.. Bookmark and Share

Search here again if you need more info!
Custom Search



Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy