Lesson 4 | Working with the Thread class |
Objective | Create and use the Thread class. |
Creating Threads by extending the Threads Class
Java provides two approaches for creating and using
threads:
- Derive your thread class from the standard
Thread
class
- Implement the
Runnable
interface in your thread class
Both the Thread
class and the Runnable
interface are defined in the java.lang
package,
which is automatically imported into every Java program.
The Thread
class actually implements the Runnable
interface, which defines a method named run()
that
is at the heart of all threads. The run()
method is where code is placed to be executed in a thread.
Deriving from the Thread class
The first approach to creating a multithreaded program involves defining a class that extends the Thread
class and overrides the run()
method:
class Searcher extends Thread {
public Searcher() { }
public void run() {
// Perform a lengthy operation such as a database search
}
}
To create and run the Searcher
thread, you create an instance of the Searcher
object and call the
start()
method, which is defined in the Thread
class:
Thread thread = new Searcher();
thread.start();
What will the following code print when run?
class Resource {
public String data = "DATA";
}
class Helper implements Runnable {
Resource r; int number;
public Helper(Resource r, int number) {
this.r = r; this.number = number;
}
public void run(){
synchronized(r) {
r.data = "DATA "+number;
r.notifyAll();
r.data = "DATA";
}
}
}
public class Driver {
public static void main(String[] args) {
Resource r = new Resource();
Helper h = new Helper(r, 1);
Thread t = new Thread(h);
t.start();
synchronized(r) {
System.out.println(r.data);
}
}
}
Select 1 option:
- It will print DATA 1.
- It will print DATA.
- Output cannot be determined for sure.
- Exception at run time.
- It will not compile.
Answer: b
Explanation:
b. Even though Helper thread calls notifyAll(), the lock on r is not released until the thread gets out of the synchronized block.
The concept to note here is that calling notify/notifyAll does not release the lock. A lock is not released until the thread exists as a synchronized block or method. In this case, there are two possibilities:
- Possibility 1: The
main
thread runs and acquires the lock on 'r' first, and the Helper thread is locked until the main
thread finishes. In this case, the main
thread will print "DATA".
- Possibility 2: The Helper thread runs and acquires the lock on 'r'. The
main
thread will be blocked.
In this case, the Helper thread changes the value of r.data to "DATA 1", calls notifyAll()
, and then changes the value back to "DATA".
At the end of the synchronized block, waiting threads (main thread) will be notified. But at that time, the value of r.data is back to DATA,
which is what the main thread prints.