Java threading introduction  Thread-safety  Thread methods  Interruption  Thread scheduling  Context switching  Thread priorities  sleep()  yield()  Deadlock  Threading with Swing  invokeLater()  Thread pools  CoundDownLatch  ThreadPoolExecutor  CyclicBarrier

Threads Database Profiling Regular expressions Random numbers Compression Exceptions C Equivalents in Java
Are you an iOS developer looking to get exposure for your new apps? Submit your app here to get it included in our new site coming soon!

Java & Threads

Threads are essentially subprocesses1. Informally, you can think of them as tasks that belong to a program and that can run "simultaneously". Depending on the number of CPUs available and the number of competing threads, some of those threads actually will run in parallel on different CPUs, whilst in other cases the illusion of simultaneous execution will be achieved by "juggling" threads in and out of the available CPUs. A part of the OS called the thread scheduler takes care of deciding which threads to allocate CPU time to (on which CPUs) and when.

Who needs to know about thread programming?

In the past, people who needed to know about thread programming were generally people writing applications that dealt with multiple "requests" or "jobs" concurrently, such as a web server or maybe a web browser making simultaneous requests to download a web page and associated images. But many other "client" or "desktop" applications didn't involve threads: there was generally only one CPU on a desktop machine, so everything was just done in one thread. Even games, which often needed to create the illusion of, say, different characters simultaneously moving about, would still use one thread and just "loop through" the various characters to move on every frame. (Look at pretty much any tutorial on game programming written until fairly recently, and the first chapter will inevitably be about "the game loop"...)

But increasingly, practically every programmer needs to know about threading and parallel programming. A fundamental characteristic of "game loop" approach is that it will only occupy one processor. The only way to improve performance with this approach (aside from using better algorithms) is to increase processor speed. This hasn't mattered until recently, because single processor speeds were continually increasing. But increased performance nowadays is being achieved via increased numbers of CPUs rather than increased speed of a single CPU. This means that to get our game or calculator program to perform better, we need to put the multiple CPUs to work in parallel. And by and large, that means multiple threads.

Getting started: what are threads, and how to use them in Java

It's easier to illustrate what a thread is by diving straight in and seeing some code. We're going to write a program that "splits itself" into two simultaneous tasks. One task is to print Hello, world! every second. The other task is to print Goodbye, cruel world! every two seconds. OK, it's a silly example.

For them to run simultaneously, each of these two tasks will run in a separate thread. To define a "task", we create an instance of Runnable. Then we will wrap each of these Runnables around a Thread object.

Runnable

A Runnable object defines an actual task that is to be executed. It doesn't define how it is to be executed (serial, two at a time, three at a time etc), but just what. We can define a Runnable as follows:

Runnable r = new Runnable() {
  public void run() {
    ... code to be executed ...
  }
};

Runnable is actually an interface, with the single run() method that we must provide. In our case, we want the Runnable.run() methods of our two tasks to print a message periodically. So here is what the code could look like:

Runnable r1 = new Runnable() {
  public void run() {
    try {
      while (true) {
        System.out.println("Hello, world!");
        Thread.sleep(1000L);
      }
    } catch (InterruptedException iex) {}
  }
};
Runnable r2 = new Runnable() {
  public void run() {
    try {
      while (true) {
        System.out.println("Goodbye, " +
		"cruel world!");
        Thread.sleep(2000L);
      }
    } catch (InterruptedException iex) {}
  }
};

For now, we'll gloss over a couple of issues, such as how the task ever stops. As you've probably gathered, the Thread.sleep() method essentially "pauses" for the given number of milliseconds, but could get "interrupted", hence the need to catch InterruptedException. We'll come back to this in more detail in the section on Thread interruption and InterruptedException. The most important point for now is that with the Runnable() interface, we're just defining what the two tasks are. We haven't actually set them running yet. And that's where the Thread class comes in...

Thread

A Java Thread object wraps around an actual thread of execution. It effectively defines how the task is to be executed— namely, at the same time as other threads2. To run the above two tasks simultaneously, we create a Thread object for each Runnable, then call the start() method on each Thread:

Thread thr1 = new Thread(r1);
Thread thr2 = new Thread(r2);
thr1.start();
thr2.start();

When we call start(), a new thread is spawned, which will begin executing the task that was assigned to the Thread object at some time in the near future. Meanwhile, control returns to the caller of start(), and we can start the second thread. Once that starts, we'll actually have at least three threads now running in parallel: the two we've just started, plus the "main" thread from which we created and started the two others. (In reality, the JVM will tend to have a few extra threads running for "housekeeping" tasks such as garbage collection, although they're essentially outside of our program's control.)

Next: threading topics

On the next page, we look at the following Java threading topics:


1. A process is essentially a "heavy" unit of multitasking: as an approximation, think of it as an "application" (though it can include 'background' or 'system' processes such as your battery monitor, mouse and keyboard server, PDA synchronization tool etc). A thread, on the other hand, is a more "lightweight" unit. Different processes generally have certain resources allocated independently of one another (such as address space, file handle allocations), whereas a threads generally share the resources of their parent process.
2. We'll see later that the Thread object also encapsulates other details, such as a thread's priority.

comments powered by Disqus

 Java threading articles  Java threading and concurrency  Java profiling  Java performance graph index

Unless otherwise stated, the Java programming articles and tutorials on this site are written by Neil Coffey. Suggestions are always welcome if you wish to suggest topics for Java tutorials or programming articles, or if you simply have a programming question that you would like to see answered on this site. Most topics will be considered. But in particular, the site aims to provide tutorials and information on topics that aren't well covered elsewhere, or on Java performance information that is poorly described or understood. Suggestions may be made via the Javamex blog (see the site's front page for details).
Copyright © Javamex UK 2013. All rights reserved.