Explore the Basics of Threads and Multithreaded Programming
Basics of Threads and Multithreaded Programming
Multithreading Basics in Java
You might be curious as to how multiple threads can execute concurrently in a Java program when your computer only has one physical processor.
The roots of multithreading actually have more to do with multitasking operating systems rather than Java.
Multitasking operating systems know how to intelligently divide processor time and share it among multiple applications.
Each application is given a small "slice" of processor time, which gives the illusion that all applications have the processor to themselves.
Threads work similarly to these multitasked applications in that they are each given a slice of processor time to execute.
However, threads can not run independently and must always execute alongside a program's main thread and memory space, which is also known
as a process.
The word multithreading can be translated as multiple threads of control or multiple flows of control.
While a traditional UNIX process always has contained and still does contain a single thread of control,
multithreading (MT) separates a process into many execution threads, each of which runs independently.
Multithreading your code can
Improve application responsiveness
Use multiprocessors more efficiently
Improve program structure
Use fewer system resources
Java's built-in Support for multithreaded Programming
Unlike some computer languages, Java provides built-in support for multithreaded programming.
A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread designates separate path of execution. Thus, multithreading is a specialized form of multitasking.
You are almost certainly acquainted with multitasking because it is supported by virtually all modern operating systems. However, there are two distinct types of multitasking:
process-based and
thread-based.
It is important to understand the difference between the two. For many readers, process-based multitasking is the more
familiar form. A process is, in essence, a program that is executing. Thus, process-based
multitasking is the feature that allows your computer to run two or more programs concurrently.
For example, process-based multitasking enables you to run the Java compiler at the same time that you are using a text editor or visiting a web site.
In process-based multitasking, a program is the smallest unit of code that can be dispatched by the scheduler.
Multitasking occurs at the application level, meaning that multiple applications are allowed to run simultaneously.
Multithreading occurs within a single application, and provides support for multiple threads of execution within an application.
A multithreaded program is comprised of individual threads that execute concurrently. A thread is a single sequence of code executing within a program. Threads give multithreaded programs multiple paths of execution, which means that the threads all execute at the same time.
Multiple threads share the same address space, therefore they can access the same objects.
Multithreaded programs contain a main thread that is responsible for executing the main program code.
Additional threads are known as worker threads and typically perform subordinate tasks to help out the main thread.
A good example of a multithreaded program is one that performs a lengthy operation such as sorting records in a database or calculating prime numbers.
The lengthy operation is performed in a worker thread, which frees the main program thread to do other things, such as respond to user input. The following figures illustrate this process:
Main Application Thread in Java
What is guaranteed by the JVM with respect to threads? [ Select 2 options: ]
If a higher priority thread is in ready to run state then a lower priority thread will not run till the higher priority thread ends.
CPU time is distributed to the threads according to thread priority.
It is usually the operating System, which decides which thread to run when and for how much time.
Threads in Java are usually System dependent.
Answer: c, d Explanation:
Simply put, there is no guarantee which thread will run when and for how much time. In some operating systems like Windows, CPU time is given to threads in ratio of their priority.
While in other operating systems like Unix, a lower priority thread executes only after higher priority thread ends.
Consider the code shown below:
public class Outer {
public A a1 = new A();
public B b1 = new B();
class A { // inner class
public synchronized void doIt() {
try {
wait(); // line 1:
System.out.println("done");
} catch (Exception e) {}
}
}
class B extends Thread {
public void run() {
a1.doIt();
}
}
public Outer() throws Exception {
b1.start(); // B thread
Thread.sleep(1000);
// line 2: insert code here
}
public static void main(String[] args) throws Exception {
new Outer();
}
}
Assume that you have run the above program. The b1 thread has just executed LINE1 and the
thread that called b1.start() is about to call.
What can you insert at LINE LINE 2, so that the program will print done and exit? [Select 1 option]
synchronized(this){ this.notifyAll(); }
synchronized(b1){ b1.notifyAll(); }
synchronized(a1){ a1.notifyAll(); }
synchronized(a1){ Thread.interrupt(); }
this.getCurrentThread().interrupt();
Answer: c
Explanation:
It is given that the b1 thread has just executed LINE1.
Now, observe that the doIt() method of A is synchronized,
which means whichever thread enters this method, that thread must acquire the lock for the A object referred to by a1.
In this case, it is the B thread that has called the doIt() method.
This thread then calls wait() (same as this.wait()), which means B thread will wait till some other thread calls a notify() or notifyAll() on the same A object.
Therefore, the main thread, (this is the same thread that has called the constructor of TestClass) must call a1.notifyAll() or a1.notify().
In the next lesson, you will assess the significance of threads and when they are most useful.