Advanced Java
IMP Questions for Practical — Detailed Answers
Q.1 Explain the life cycle of a thread in Java?
A thread in Java goes through a well-defined set of states during its lifetime. These states are
managed by the Java Virtual Machine (JVM) and the thread scheduler. The [Link] enum
defines the following states:
1. New (Born) State
A thread is in the New state when it has been created using the Thread class or by implementing the
Runnable interface, but the start() method has NOT yet been called.
• Example: Thread t = new Thread();
2. Runnable State
After calling start(), the thread enters the Runnable state. The thread is ready to run and is waiting
for the CPU to be allocated by the thread scheduler. A thread can move back to Runnable from
Running.
3. Running State
The thread enters the Running state when the thread scheduler picks it from the Runnable pool and
allocates CPU time to it. The run() method is executing in this state.
4. Blocked / Waiting / Timed Waiting State
A thread transitions out of the Running state into one of these states:
• Blocked – waiting to acquire a lock held by another thread.
• Waiting – waiting indefinitely for another thread (via wait(), join()).
• Timed Waiting – waiting for a specified time (via sleep(ms), wait(ms), join(ms)).
5. Terminated (Dead) State
A thread reaches the Terminated state when its run() method completes normally or an unhandled
exception occurs. Once dead, a thread cannot be restarted.
State Trigger / Condition
New Thread object created (new Thread())
Runnable start() is called
Running Thread scheduler picks the thread
Blocked/Waiting wait(), sleep(), join() or lock contention
Terminated run() completes or exception thrown
Q.2 Describe the Thread class and Runnable interface. How are they
used to create threads?
In Java, threads can be created in two primary ways: by extending the Thread class or by
implementing the Runnable interface.
1. Thread Class
The Thread class, found in [Link], provides constructors and methods to create and perform
operations on a thread. Key methods include:
• start() – Starts execution of the thread.
• run() – Contains the code to be executed by the thread.
• sleep(ms) – Causes the thread to sleep for the specified milliseconds.
• getName() / setName() – Gets/sets the thread name.
• getPriority() / setPriority() – Gets/sets thread priority.
• join() – Waits for the thread to die.
• isAlive() – Tests if the thread is still alive.
Method 1 – Extending the Thread Class
class MyThread extends Thread {
public void run() {
[Link]("Thread running: " + getName());
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
[Link]();
}
}
2. Runnable Interface
The Runnable interface (in [Link]) has a single abstract method: run(). A class implements
Runnable and provides the logic inside run(). This approach is preferred because Java supports only
single inheritance — implementing Runnable leaves the class free to extend another class.
Method 2 – Implementing the Runnable Interface
class MyRunnable implements Runnable {
public void run() {
[Link]("Runnable thread running");
}
}
public class Main {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
[Link]();
}
}
Feature Thread Class Runnable Interface
Inheritance Extends Thread (single) Implements Runnable (flexible)
Usage Less preferred Preferred approach
Code Reuse Limited Better – separates task from thread
Lambda Support No Yes (functional interface)
Q.3 What is synchronization? Why is it important in multithreading?
Synchronization in Java is a mechanism that ensures that only one thread at a time can access a
shared resource (such as a variable, method, or block of code). It is achieved using the
synchronized keyword.
Why is Synchronization Important?
In a multithreaded environment, multiple threads share common resources. If two or more threads
access and modify the same data simultaneously, it leads to a Race Condition, producing
inconsistent or incorrect results. Synchronization prevents this.
• Data Consistency – Ensures shared data is not corrupted.
• Prevents Race Conditions – Only one thread modifies data at a time.
• Thread Safety – Makes code safe for concurrent use.
• Prevents Dirty Reads – Ensures a thread reads fully updated data.
Types of Synchronization
• Method-level Synchronization – The entire method is locked.
• Block-level Synchronization – Only a specific block is locked (more efficient).
Example – Synchronized Method
class Counter {
int count = 0;
synchronized void increment() {
count++;
}
}
// Only one thread can call increment() at a time.
// This prevents count from being corrupted by concurrent access.
Key Concept – Monitor Lock: Every Java object has an intrinsic lock (monitor). When a thread
enters a synchronized method/block, it acquires the lock. Other threads attempting to enter the same
synchronized section are blocked until the lock is released.
Q.4 Explain thread priorities and daemon threads in Java?
A. Thread Priorities
Every Java thread has a priority that helps the thread scheduler decide the order in which threads
are scheduled for execution. Priorities are integers ranging from 1 (MIN_PRIORITY) to 10
(MAX_PRIORITY), with a default of 5 (NORM_PRIORITY).
Constant Value Meaning
Thread.MIN_PRIORITY 1 Lowest priority
Thread.NORM_PRIORITY 5 Default priority
Thread.MAX_PRIORITY 10 Highest priority
Important Notes: Thread priority is a hint to the scheduler — it is platform-dependent and not
guaranteed. Higher-priority threads are generally given preference, but this is not always the case.
Thread t = new Thread();
[Link](Thread.MAX_PRIORITY); // Set to 10
[Link]([Link]()); // Output: 10
B. Daemon Threads
A daemon thread is a low-priority background thread that provides services to user (non-daemon)
threads. The JVM automatically terminates all daemon threads when all user threads finish
execution, even if daemon threads are still running.
• Examples: Garbage Collector, finalizer threads, background auto-save.
• Created using: [Link](true) — must be called before start().
• Check status using: [Link]() — returns true/false.
Thread t = new Thread(() -> {
while (true) {
[Link]("Daemon running...");
}
});
[Link](true); // Mark as daemon BEFORE start
[Link]();
// When main thread ends, this daemon thread is killed automatically.
Feature User Thread Daemon Thread
JVM Exit JVM waits for it to finish JVM exits even if running
Purpose Main application logic Background support services
Default Yes (threads are user by default) No (must be set explicitly)
Example Main thread, application threads Garbage Collector
Q.5 Explain the File class and different types of file streams in Java?
A. The File Class
The File class in Java is part of the [Link] package. It represents a file or directory path in the file
system. Importantly, it does not read or write data — it is used to manage and inspect file/directory
metadata.
Commonly Used Methods of the File Class
Method Description
exists() Returns true if the file/directory exists
getName() Returns the name of the file or directory
getPath() Returns the path as a String
isFile() Returns true if it is a file
isDirectory() Returns true if it is a directory
length() Returns the size of the file in bytes
createNewFile() Creates a new empty file
delete() Deletes the file or directory
mkdir() Creates a new directory
list() Returns array of files/dirs in a directory
File f = new File("[Link]");
if (![Link]()) {
[Link]();
[Link]("File created: " + [Link]());
}
B. File Streams in Java
Java provides a rich set of stream classes in [Link] for reading and writing data. Streams are
broadly divided into two types:
1. Byte Streams (Binary Data)
Used to read/write raw binary data (images, audio, etc.). Base classes: InputStream and
OutputStream.
Class Direction Purpose
FileInputStream Read Reads raw bytes from a file
FileOutputStream Write Writes raw bytes to a file
BufferedInputStream Read Buffers input for efficiency
BufferedOutputStream Write Buffers output for efficiency
DataInputStream Read Reads Java primitives (int, double, etc.)
DataOutputStream Write Writes Java primitives to file
ObjectInputStream Read Reads serialized Java objects
ObjectOutputStream Write Writes (serializes) Java objects
// Writing bytes to a file
FileOutputStream fos = new FileOutputStream("[Link]");
[Link](65); // Writes 'A'
[Link]();
// Reading bytes from a file
FileInputStream fis = new FileInputStream("[Link]");
int b = [Link]();
[Link]((char) b); // Output: A
[Link]();
2. Character Streams (Text Data)
Used to read/write text data. Handles character encoding automatically. Base classes: Reader and
Writer.
Class Direction Purpose
FileReader Read Reads characters from a text file
FileWriter Write Writes characters to a text file
BufferedReader Read Reads text line by line efficiently
BufferedWriter Write Writes text with buffering
PrintWriter Write Writes formatted text (println, printf)
InputStreamReader Read Bridges byte stream to character stream
// Writing text to a file
FileWriter fw = new FileWriter("[Link]");
BufferedWriter bw = new BufferedWriter(fw);
[Link]("Hello, Java File Handling!");
[Link]();
[Link]();
// Reading text from a file
FileReader fr = new FileReader("[Link]");
BufferedReader br = new BufferedReader(fr);
String line = [Link]();
[Link](line); // Output: Hello, Java File Handling!
[Link]();
Summary – Stream Types
Category Base Read Class Base Write Class Use For
Byte Streams InputStream OutputStream Binary/raw data
Character Streams Reader Writer Text/character data
Answers compiled from Advanced Java study material — Unit 2 & Unit 3. For programming examples, refer to the
practical file.