Threads and Process
Threads and Process
Thread in java
In Java, a thread represents an independent flow of executionwithin a program. Threads
allow concurrent execution of multiple tasks, allowing your program to perform multiple
operations simultaneously or in parallel.
A thread is a basic processing unit to which an operating system allocates processor time,
and more than one thread can be executing code inside a process
Here are some key points about threads in Java:
1. Thread Creation: You can create a thread in Java by eitherextending the `Thread` class
or implementing the `Runnable` interface. Extending the `Thread` class allows you to
define your own thread class, while implementing the `Runnable` interface allows you to
separate the task logic from the threaditself.
2. Main Thread: When a Java program starts, it automaticallycreates a main thread that
executes the `main()` method. Themain thread is responsible for executing the program's
entry point and can spawn additional threads as needed.
3. Thread Lifecycle: A thread in Java goes through variousstates during its lifecycle.
These states include:
- New: The thread has been created but not yet started.
- Runnable: The thread is ready to run, waiting for theprocessor.
- Running: The thread is currently being executed.
- Blocked: The thread is temporarily blocked and waiting for acertain condition.
- Terminated: The thread has completed its execution or beenterminated.
4. Thread Scheduling: The Java Virtual Machine (JVM) handlesthread scheduling, deciding
which thread to execute based on factors such as thread priority, thread state, and the
underlying operating system's scheduling algorithm. The JVM employs a preemptive
scheduling model, allowing threads to be interrupted and switched by the scheduler.
5. Thread Priorities: Each thread in Java has a priority value ranging from 1 to 10, with
1 being the lowest priority and 10 being the highest. Thread priorities can influence the
order inwhich threads are executed, although the exact behavior is dependent on the
underlying operating system.
7. Thread Safety: Thread safety refers to the ability of code or data structures to be safely
accessed and manipulated by multiple threads concurrently without causing unexpected
behavior or data corruption. Ensuring thread safety is crucial toprevent race conditions and
maintain the integrity of shared resources.
9. Thread Communication: Threads can communicate with each other by using various
synchronization constructs such as
`wait()`, `notify()`, and `notifyAll()`. These methods allow threads to wait for certain
conditions to be met and signal otherthreads when those conditions are fulfilled.
10. Thread Pooling: Creating and managing a large number ofthreads can be resource-
intensive. Thread pooling is a technique where a fixed set of threads is created in advance
and reused to execute multiple tasks. This reduces the overhead of thread creation and
provides better control over resource utilization.
Threads are a powerful mechanism in Java that enable concurrent and parallel execution.
Understanding threads and their lifecycle, synchronization, and coordination mechanisms is
essential for developing robust and efficient multi-threaded applications.
Creating Threads in Java
In Java, you can create threads by either extending the
`Thread` class or implementing the `Runnable` interface. Here'show you can create threads
using both approaches:
The significant differences between extending Thread class and implementing Runnable
interface:
• When we extend Thread class, we can’t extend any other class even we require and
When we implement Runnable, we can save a space for our class to extend any other
class in future or now.
• When we extend Thread class, each of our thread creates unique object and associate
with it. When we implements Runnable, it shares the same object to multiple threads.
- Override the `run()` method, which contains the code to beexecuted by the thread.
- Create an instance of your custom thread class and call the `start()` method to start the
execution of the thread.
Example:
EXAMPLE 1
class Test extends Thread
{
public void run()
{
System.out.println("Run method executed by child Thread");
}
public static void main(String[] args)
{
Test t = new Test();
t.start();
System.out.println("Main method executed by main thread");
}
}
EXAMPLE 2
class MyThread extends Thread {@Override
public void run() {
// Code to be executed by the thread
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args)
{
MyThread myThread = new MyThread();
myThread.start(); // Start the thread
}
}
- Implement the `run()` method in the class, which containsthe code to be executed by
the thread.
- Create a `Thread` object, passing your `Runnable` instanceto the `Thread` constructor.
- Call the `start()` method on the `Thread` object to start theexecution of the thread.
Example:
```java
class MyRunnable implements Runnable {
public void run() {
// Code to be executed by the thread
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable);
myThread.start(); // Start the thread
}
}
EXAMPLE 2
// Java program to illustrate defining Thread
// by implements Runnable interface
class Geeks {
public static void m1()
{
System.out.println("Hello Visitors");
}
}
{
System.out.println("Run method executed by child Thread");
}
public static void main(String[] args)
{
Test t = new Test();
t.m1();
Thread t1 = new Thread(t);
t1.start();
System.out.println("Main method executed by main thread");
}
}
In both approaches, when you call the `start()` method on the thread object, it will internally
invoke the `run()` method of the thread. The `run()` method contains the actual code that will
beexecuted by the thread.
It's important to note that creating and starting a thread doesnot guarantee immediate
execution. The JVM handles the scheduling of threads based on the underlying
operating system's scheduling algorithm and other factors like thread priorities.
By creating and starting threads, you can achieve concurrent execution of tasks and leverage
the power of multi-threading inyour Java programs.
Java Thread Methods
The main thread is created automatically when our program is started. To control it we must
obtain a reference to it. This can be done by calling the method currentThread( ) which is
present in Thread class. This method returns a reference to the thread on which it is called. The
default priority of Main thread is 5 and for all remaining user threads priority will be inherited
from parent to child.
// Class 1
// Main class extending thread class
public class Test extends Thread {
// Class 2
// Helper class extending Thread class
// Child Thread class
class ChildThread extends Thread {
1. New: In this initial state, a thread is created, but it has not yet started its execution. The
thread is not yet eligible for executionuntil the `start()` method is called.
2. Runnable: Once the `start()` method is called on a thread, it enters the runnable state. In
this state, the thread is eligible to be scheduled by the operating system for execution.
However,
it does not necessarily mean that the thread is currently running. The thread may be
waiting for its turn to be allocatedCPU time.
3. Running: When a thread is selected by the thread scheduler,it enters the running state. In
this state, the thread's code is being executed by the CPU.
- When it is waiting for a monitor lock to enter a synchronized block or method. For
example, when `synchronized` keyword isencountered, and the lock is not available.
- When it is waiting for a certain condition to be met, such as waiting for data to be
available from an I/O operation.
- When it is put to sleep using the `Thread.sleep()` method or when it is waiting for a
specified time using methods like
`wait()`, `join()`, or `park()`.
In the blocked/waiting state, the thread temporarily gives upthe CPU and does not
consume any CPU time until it is unblocked or notified.
5. Timed Waiting: Similar to the blocked/waiting state, a threadcan also enter a timed
waiting state where it waits for a specified period of time. This state occurs when methods
like
`Thread.sleep()` or `Object.wait(timeout)` are used.
6. Terminated: A thread enters the terminated state when it completes its execution or is
explicitly terminated by calling the
`stop()` method (which is deprecated) or when its `run()`method returns.
It's important to note that the transitions between different states are managed by the JVM
and the underlying operatingsystem. The thread scheduler determines when to switch
between threads and which thread to run based on various factors such as thread
priorities, thread states, and the operating system's scheduling algorithm.
Understanding the thread lifecycle allows you to write efficient and well-coordinated multi-
threaded programs. Proper synchronization and coordination mechanisms should be usedto
manage the transitions between different thread states and to avoid race conditions and
other concurrency issues.
Multithreading in Java
Multithreading in Java allows you to execute multiple threads concurrently, enabling your
program to perform multiple tasks simultaneously or in parallel. Multithreading can improve
the efficiency and responsiveness of your application, especially fortasks that involve I/O
operations, waiting for external resources,or performing computationally intensive
operations. Here are some key points to understand about multithreading in Java:
1. Thread Creation: You can create multiple threads in Java byextending the `Thread` class
or implementing the `Runnable` interface, as mentioned in the previous response. Each
threadrepresents an independent flow of execution within your program.
3. Thread Coordination: Threads can communicate and coordinate with each other using
synchronization mechanisms like `wait()`, `notify()`, and `notifyAll()`. These methods allow
threads to wait for certain conditions to be met and signal otherthreads when those
conditions are fulfilled.
4. Thread Priorities: Each thread in Java has a priority value ranging from 1 to 10, with
1 being the lowest priority and 10 being the highest. Thread priorities can influence the
order inwhich threads are executed, although the exact behavior depends on the
underlying operating system's thread scheduler.
5. Thread Pooling: Creating and managing a large number ofthreads can be resource-
intensive. Thread pooling is a technique where a fixed set of threads is created in advance
and reused to execute multiple tasks. This reduces the overhead of thread creation and
provides better control over resource utilization.
6. Thread Safety: Thread safety refers to the ability of code ordata structures to be safely
accessed and manipulated by
resources and enable communication between threads or processes. In Java, you can use
various synchronization mechanisms and IPC techniques to ensure thread safety and
coordination. Let's explore synchronization and IPC in threads:
Synchronization:
1. Mutual Exclusion: Synchronization provides mutual exclusion, ensuring that only one
thread can access a shared resource or critical section of code at a time. This prevents race
conditions and data corruption. In Java, you can achieve mutual exclusion using the
`synchronized` keyword, which can be applied to methods or blocks of code.
2. Locks: Java provides explicit locks through the `Lock` interface and its
implementations, such as `ReentrantLock`. Locks allow threads to acquire and release
locks explicitly, providing more fine-grained control over synchronization thanintrinsic
locks (`synchronized` keyword). Locks also support features like fairness, condition
variables, and timeouts.
3. Condition Variables: Condition variables enable threads to wait for specific conditions
to be met before proceeding. In Java, condition variables are associated with locks and can
beused with the `await()`, `signal()`, and `signalAll()` methods of the `Condition` interface.
Threads can wait on a condition variable until another thread signals or signals all waiting
threads.
Inter-Process Communication (IPC):
1. Shared Memory: IPC using shared memory involves creatinga shared memory region that
multiple threads or processes can
access. Threads can read from and write to this shared memory region, allowing them to
exchange data or communicate. Proper synchronization mechanisms like locks orsemaphores
should be used to manage access to shared memory to avoid race conditions.
4. Remote Procedure Calls (RPC): RPC is a mechanism wherea thread or process can
invoke a method or procedure on a remote thread or process, as if it were a local call. This
allows threads or processes to communicate and exchange data by invoking methods on
remote objects.
It's important to choose the appropriate synchronization and IPC mechanisms based on the
requirements of your application. Consider factors such as the nature of the shared resources,
the desired level of coordination, and the potential for contention or deadlock. Effective use
of synchronization and IPC can ensure thread safety, prevent data corruption, andfacilitate
efficient communication between threads or processes.
Certainly! Here are a few more details about synchronizationand inter-process
communication (IPC) in threads:
Synchronization:
2. Volatile Variables: The `volatile` keyword in Java is used to declare variables whose
values may be modified by different threads. When a variable is declared as volatile, changes
madeto it by one thread are immediately visible to other threads. It ensures the visibility of
changes across threads, but it does not provide atomicity or mutual exclusion.
3. Shared Files: Threads or processes can communicate byreading from and writing to
shared files. Synchronization mechanisms such as file locks or explicit coordination are
necessary to ensure that multiple threads/processes do notaccess the file simultaneously
and cause conflicts.
one thread/process to invoke methods on objects residing in remote JVMs, providing a way
for inter-process communicationacross a network.
Synchronization and IPC mechanisms should be chosen basedon the specific requirements of
your application, such as the type of communication needed, the level of coordination
required, and the performance characteristics desired. It's important to handle
synchronization and IPC carefully to avoid issues like deadlocks, race conditions, and data
corruption.
// main method
public static void main(String argvs[])
{
// creating an object of the class ThreadState
obj = new ThreadState();
t1 = new Thread(obj);
// thread t1 is spawned
// The thread t1 is currently in the NEW state.
System.out.println("The state of thread t1 after spawning it - " + t1.getState());
t2.getState());
// try-catch block for the smooth flow of the program
try
{
// moving the thread t1 to the state timed waiting
Thread.sleep(200);
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
System.out.println("The state of thread t2 after invoking the method sleep() on it - "+
t2.getState() );
Process Thread
Each process has its memory area that is not A process's threads share the same
shared by any other process. memory area.
Processes can execute on different CPUs, Threads can only execute on one CPU
allowing for real parallelism. at a time and can only provide
pseudo-parallelism.
When one process fails, it does not affect the If one thread fails, the entire process
other processes. may suffer.
Because of the expense associated with Threads are more scalable since they
designing and monitoring processes, they are are lightweight and easier to build
less scalable. and manage.
Because processes cannot share memory, Threads inside a process can use
synchronization needs IPC techniques such as shared memory and lock objects to
semaphores, mutexes, or pipes. synchronize.
Because of the expense of context switching, Threads can use CPU resources more
processes might require additional CPU effectively since switching between
resources. them requires less overhead.
Processes are more secure because they Threads are more exposed to security
execute in their memory area, decreasing the concerns since they share the same
possibility of one process accessing the memory space and can directly access
memory of another. each other's memory.
Processes are more portable since they can Threads may be less portable because
execute on various operating systems with their behavior varies depending on
varying architectures. the underlying operating system and
hardware.
When a process crashes, it does not affect If a thread fails, the entire process
other processes operating on the system. might fail.
Processes have separate memory spaces, Threads can communicate with each
while threads share the same memory space other more easily and can access the
as the parent process. same data structures.
Processes are often used for processes that Threads are used for operations that
must be separated from one another. must cooperate.