Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java 101: Understanding Java threads, Part 1: Introducing threads and runnables

Learn how to improve Java application performance using Java threads

  • Print
  • Feedback

This article is the first in a four-part Java 101 series exploring Java threads. Although you might think threading in Java would be challenging to grasp, I intend to show you that threads are easy to understand. In this article, I introduce you to Java threads and runnables. In subsequent articles, we'll explore synchronization (via locks), synchronization problems (such as deadlock), the wait/notify mechanism, scheduling (with and without priority), thread interruption, timers, volatility, thread groups, and thread local variables.

Note that this article (part of the JavaWorld archives) was updated with new code listings and downloadable source code in May 2013.

What is a thread?

Conceptually, the notion of a thread is not difficult to grasp: it's an independent path of execution through program code. When multiple threads execute, one thread's path through the same code usually differs from the others. For example, suppose one thread executes the byte code equivalent of an if-else statement's if part, while another thread executes the byte code equivalent of the else part. How does the JVM keep track of each thread's execution? The JVM gives each thread its own method-call stack. In addition to tracking the current byte code instruction, the method-call stack tracks local variables, parameters the JVM passes to a method, and the method's return value.

When multiple threads execute byte-code instruction sequences in the same program, that action is known as multithreading. Multithreading benefits a program in various ways:

  • Multithreaded GUI (graphical user interface)-based programs remain responsive to users while performing other tasks, such as repaginating or printing a document.
  • Threaded programs typically finish faster than their nonthreaded counterparts. This is especially true of threads running on a multiprocessor machine, where each thread has its own processor.

Java accomplishes multithreading through its java.lang.Thread class. Each Thread object describes a single thread of execution. That execution occurs in Thread's run() method. Because the default run() method does nothing, you must subclass Thread and override run() to accomplish useful work. For a taste of threads and multithreading in the context of Thread, examine Listing 1:

Listing 1. ThreadDemo.java

// ThreadDemo.java
class ThreadDemo
{
   public static void main (String [] args)
   {
      MyThread mt = new MyThread ();
      mt.start ();
      for (int i = 0; i < 50; i++)
           System.out.println ("i = " + i + ", i * i = " + i * i);
   }
}
class MyThread extends Thread
{
   public void run ()
   {
      for (int count = 1, row = 1; row < 20; row++, count++)
      {
           for (int i = 0; i < count; i++)
                System.out.print ('*');
           System.out.print ('\n');
      }
   }
}

Listing 1 presents source code to an application consisting of classes ThreadDemo and MyThread. Class ThreadDemo drives the application by creating a MyThread object, starting a thread that associates with that object, and executing some code to print a table of squares. In contrast, MyThread overrides Thread's run() method to print (on the standard output stream) a right-angle triangle composed of asterisk characters.

  • Print
  • Feedback

Resources
  • Learn more about Java: See the complete listing for Jeff Friesen's Java 101 series -- archived on JavaWorld.
  • Also see the Java Tips series: More than five years of compiled tips from JavaWorld's expert readers.