What is a Thread?
Almost every operating system supports independently running programs called processes. Threading is a facility to allow multiple activities to coexist within a single process. Java is the first programming language to explicitly include threading within the language itself, rather than treating it as a facility of the underlying OS.
Threads are sometimes called as lightweight processes. Like processes,they work independently and each thread has its own stack, program counter, and local variables. Even though they have their own stuff, threads within a process are less insulated from each other than separate processes are. They share memory space, file handles, etc. This means they have access to the same variables and objects. While this makes it easier for them to share information, the programmer must be very careful not to let them interfere with each other in the same process.
The Java thread facility and API is very simple. However, writing complex programs that use threading effectively is not quite as simple because of the thread interference problem, I mentioned earlier.
Every Java Program Uses Threads
Every Java program must have at least one thread, the main thread. When the program starts running, the JVM creates this thread and calls the main() method within that thread.
There are other threads created by the JVM that you usually don't notice them running in the background. These are for garbage collection, object finalization and for other stuff.
Why Do We Need Threads?
There are many reasons to use threads in your Java programs. If you use Swing, Servlets,
RMI, or Enterprise JavaBeans (EJB) technology, you may already be using threads without
realizing it. Some of the reasons for using threads are that they can help to:
- They make the UI more responsive,
- Take advantage of multiprocessor systems,
- Perform asynchronous or background processing.
Threads Are Simple But Sometimes Risky
While the Java thread facility is very easy to use, there are several risks you should try to avoid when you create multithreaded programs. When multiple threads are required to access the same memory space the programmer needs to make sure that they coordinate their access so that the changes made on data by any thread is not lost.
The Java language provides two keywords for this purpose: synchronized and volatile. We will explore the use and meaning of these keywords later in this tutorial.
When accessing variables from more than one thread, you must ensure that the access is properly synchronized. For simple variables, it may be enough to declare the variable volatile, but in most situations, you will need to use synchronization. If you are going to use synchronization to protect access to shared variables, you must make sure to use it everywhere in your program where the variable is accessed.
Example: Using a thread for timing and a thread to do the work
The following example uses two threads, one for timing and one to do actual work. The main thread finds and prints the even numbers using a very straightforward algorithm. Before it starts, it creates and starts a timer thread, which will sleep for ten seconds, and then sets a flag that the main thread will check. After 2 milliseconds, the main thread will stop. Note that the shared flag is declared volatile.