What Are Threads?

   

A unique property of Java is its built-in support for threads. Threads allow you to do many tasks simultaneously, or at least it seems that the tasks are working simultaneously . As you'll see later in this chapter, most of the time, there is actually only one thread running at a time. A thread is really nothing but a sequential flow of control within a program. In multithreaded programs, there are multiple flows of control. For the purposes of this chapter, a "flow of control" is referred to as a task.

If an application could only perform a new task when another task was completed, your applications would be severely limited. Fortunately, Java has built-in thread support that allows programmers to schedule multiple tasks to work together concurrently to accomplish the overall goal of the application. This chapter covers how threads can be used in Java programs to increase the performance and scalability of your applications.

Think of a typical application. There are usually screens to view and capture information from the user. There might be a need to retrieve and store that information in some form of persistent store such as a database. And usually, other system-type services are happening in the background that the end- user might not be aware of. Imagine how the application would perform if one task had to finish completely before any other tasks could begin. This obviously would not be efficient and probably would cause big problems with performance and scalability.

Fortunately, this is not how things really work. Operating systems, the Java Virtual Machine (JVM), and multithreaded programming combine their efforts to allow Java developers to create multiple threads to seemingly accomplish many tasks simultaneously.

With some hardware systems, you might only have a single processor, and that single processor has to take on all these tasks. Even with multiple processors, true parallelism might never be fully appreciated. To manage these multiple tasks or threads, a concept called multitasking was invented. In reality, the processor is still only doing one thing at any one time, but it switches among them so fast that it seems like it is doing them all simultaneously. Fortunately, modern computers work much faster than human beings, so you hardly even notice that this is happening.

Think about it in this way: Each program is assigned a process. That program then breaks up its tasks into threads. Although you might not have realized it at the time, you have already worked with threads. When you wrote your first program back in Chapter 1, "Object-Oriented Programming," you were actually using your first thread. Of course, you didn't have to do anything special because you actually wrote a program that contained a single thread. When you started the HelloWorld program, a main thread of control was created for you. This is shown in Figure 11.1.

Figure 11.1. Here is a single thread within a program.

graphics/11fig01.gif

Sometimes, the term lightweight process is also used instead of thread. A thread and a process are similar in that both are a sequential flow of control. A thread is considered lightweight because it is started from a process. This does not mean that a thread must have a process always associated with it; it's just started from a process. There are ways to have a thread running without a process. This will be explained along with daemon threads later in this chapter. For now, it's worthwhile to know that a thread needs to be started by a program and must share the resources allocated to it by the operating system. Each thread occupies some private space, however. This allows the thread to act independently of the other threads running (see Figure 11.2).

Figure 11.2. Two running threads can act concurrently within a program.

graphics/11fig02.gif

As stated earlier, when you have a multithreaded program, the threads might not really be running at the same time. Putting aside multiple CPUs and parallel processing for a moment, there is really only one thread running at all times. The reason is that each thread is given a little amount of time to execute by the CPU and then it has to wait while another thread is allowed to run. Each operating system or Java Virtual Machine can handle this differently. Sometimes the thread might get to run to completion and then another thread can run. This is known as non-preemptive. Other times, a thread will be interrupted so that other threads can run. This is known as preemptive. There is also the case in which only higher threads can preempt other threads. This material is slightly below the needs of this discussion, but you should be aware that a thread might have to compete for CPU time against the other threads that are running. This situation is shown in Figure 11.2. The good news is that the speed at which this happens is so fast, it gives the appearance that multiple threads are running at the same time.

The most important point to take from all this is that threads will be interrupted from time to time to allow for other threads to run. Later in this chapter, you will see how this affects Java programs and what interesting problems arise from this and how you can manage these problems. Figure 11.3 shows two separate threads competing for execution time.

Figure 11.3. Here, two threads are competing for processor time.

graphics/11fig03.gif

   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net