thread notes
thread notes
The life cycle consists of various stages, and understanding these stages helps in
creating efficient multi-threaded programs.
try {
// Timed Waiting State: Thread will sleep for 3
seconds
Thread.sleep(3000);
try {
// Main thread waits for myThread to complete
myThread.join(); // Waiting for myThread to finish,
makes main thread enter waiting state
Thread method :
a Thread is a unit of execution, and the Thread class provides various methods to
control and manage the behavior of threads. Here are some important Thread
methods in Java that you can use to work with threads:
run():
The run() method contains the code to be executed by the thread. You override this
method to define what the thread does. The run() method is executed automatically
when you call start() on a thread.
join():
This method is used to pause the execution of the current thread until the thread on
which join() was called has finished executing. It can also accept a timeout to
specify how long to wait.
Thread t1 = new Thread();
t1.start();
t1.join(); // Current thread will wait for t1 to complete
interrupt():
This method interrupts a thread that is currently sleeping, waiting, or running. If a
thread is sleeping or waiting, it will throw an InterruptedException.
thread.interrupt(); // Interrupts the thread
isAlive():
This method checks whether a thread is still alive (i.e., if it has been started but not
yet finished).
getName():
This method returns the name of the thread.
String threadName = thread.getName(); // Get the name of the
thread
setName(String name):
This method sets the name of the thread.
thread.setName("MyThread"); // Set the name of the thread
setPriority(int priority):
This method sets the priority of the thread. The priority should be an integer value
between Thread.MIN_PRIORITY (1) and Thread.MAX_PRIORITY (10), with the
default being Thread.NORM_PRIORITY (5).
thread.setPriority(Thread.MAX_PRIORITY); // Set maximum priority
getPriority():
This method returns the current priority of the thread.
int priority = thread.getPriority(); // Get the current priority of the
thread
yield():
This static method causes the current thread to yield (temporarily pause) its
execution, allowing other threads of the same priority to execute.
currentThread():
This static method returns a reference to the currently executing thread.
Thread current = Thread.currentThread(); // Get the current thread
getId():
This method returns the unique ID of the thread.
long threadId = thread.getId(); // Get the ID of the thread
example code –
try {
Thread.sleep(2000); // Sleep for 2 seconds
System.out.println("Thread " + getName() + " woke
up.");
} catch (InterruptedException e) {
System.out.println("Thread " + getName() + " was
interrupted.");
}
t1.setName("Thread-1");
t2.setName("Thread-2");
t1.start(); // Start t1
t2.start(); // Start t2
try {
t1.join(); // Wait for t1 to finish
t2.join(); // Wait for t2 to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
1. InterruptedException
Thread.sleep(long millis)
Object.wait()
Thread.join()
Thread.yield() (in some cases)
Ex –
class MyThread extends Thread {
try {
Thread.sleep(5000);
System.out.println("Thread completed.");
} catch (InterruptedException e) {
t.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
Output:
2. IllegalThreadStateException
Example:
Explanation:
The t thread is started, and then the start() method is called again on the
same thread, which throws an IllegalThreadStateException.
Output:
Thread is running
Caught exception: java.lang.IllegalThreadStateException: Thread
already started.
Explanation:
Output:
Caught exception: java.lang.NullPointerException
Example:
import java.util.concurrent.*;
executor.submit(() -> {
System.out.println("Task 2 is running");
}); // This will be rejected as the thread pool size is
1
Explanation:
Output:
arduino
Copy
Task 1 is running
Task 2 is running
Caught exception:
java.util.concurrent.RejectedExecutionException: Task already
completed
5. SecurityException
This exception occurs when a security manager denies access to the thread,
for example, when a thread is trying to modify the system properties or
access restricted resources.
Example:
public class SecurityExceptionExample {
public static void main(String[] args) {
Thread t = new Thread(() -> {
System.setProperty("user.name", "newuser"); //
Modifying system properties
});
try {
t.start();
} catch (SecurityException e) {
System.out.println("Caught exception: " + e);
}
}
}
Output:
Caught exception: java.lang.SecurityException: Unable to modify
system properties
You can handle exceptions in threads using standard try-catch blocks. If the thread
is performing some potentially risky operation, catch the specific exception type
and handle it appropriately.
In Java, each thread has a priority that helps the thread scheduler determine the
order in which
threads should be executed. Thread priority is an integer value that ranges from 1
to 10:
1. setPriority(int newPriority)
o Purpose: Sets the priority of a thread.
o Usage Example:
Thread t = new Thread();
t.setPriority(Thread.MAX_PRIORITY); // Sets the priority to 10
2. getPriority()
o Purpose: Returns the current priority of the thread.
o Usage Example:
int priority = t.getPriority();
System.out.println("Thread Priority: " + priority);
• Setting a thread’s priority to a value outside the range (1 to 10) will throw an
IllegalArgumentException.
Synchronization
In Java, synchronization is a mechanism used to control access to shared resources
by multiple threads in a concurrent environment. It ensures that only one thread
can access the shared resource at a time, preventing issues such as data corruption,
race conditions, and inconsistent results.
Why Synchronization is Needed:
In a multithreaded environment, multiple threads may try to access and modify the
same shared resource simultaneously. If threads are allowed to access the resource
at the same time, it can lead to race conditions and inconsistent data.
Synchronization is a way to avoid this problem by ensuring that only one thread
can access the resource at a time.
Key Concepts of Synchronization:
1. Critical Section: The code that accesses and modifies shared resources.
When one thread enters the critical section, other threads must wait until it
exits.
2. Race Condition: A situation where the output of a program depends on the
sequence or timing of other uncontrollable events (such as threads' execution
order). This often leads to inconsistent results.
// Thread 1
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// Thread 2
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
// Start threads
t1.start();
t2.start();
2. Synchronized Blocks
Instead of synchronizing the entire method, you can synchronize a block of
code within a method. This is useful if only part of the method needs
synchronization, improving performance by reducing contention.
Syntax:
java
Copy
synchronized(object) {
// critical section
}
Example:
java
Copy
class Counter {
private int count = 0;
void increment() {
synchronized(this) {
count++;
}
int getCount() {
synchronized(this) {
return count;
}
}
}
// Thread 1
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// Thread 2
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
// Start threads
t1.start();
t2.start();
class Counter {
private int count = 0;
private Lock lock = new ReentrantLock(); // ReentrantLock instance
void increment() {
lock.lock(); // Acquire the lock
try {
count++;
} finally {
lock.unlock(); // Release the lock
}
}
int getCount() {
lock.lock();
try {
return count;
// Thread 1
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// Thread 2
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// Start threads
4. volatile Keyword
The volatile keyword in Java ensures that updates to a variable are immediately
visible to all threads. While it doesn't prevent race conditions or provide
atomicity like synchronization, it guarantees visibility.
Example:
java
void increment() {
count++;
}
int getCount() {
return count;
}
}
// Thread 1
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
// Thread 2
// Start threads
t1.start();
t2.start();
5. Atomic Variables
Java provides a set of atomic variables in the java.util.concurrent.atomic
package (e.g., AtomicInteger, AtomicLong, etc.), which offer thread-safe
operations without the need for synchronization.
Example:
import java.util.concurrent.atomic.AtomicInteger;
class Counter {
void increment() {
count.incrementAndGet();
int getCount() {
return count.get();
// Thread 1
counter.increment();
});
// Thread 2
counter.increment();
});
// Start threads
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();