0% found this document useful (0 votes)
5 views7 pages

Java Thread Life Cycle and Synchronization

Uploaded by

Kunal Khadse
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views7 pages

Java Thread Life Cycle and Synchronization

Uploaded by

Kunal Khadse
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Life Cycle of Thread

There are different types of thread state are as follows as-

1. New or Born State-


The thread is in new state if you create an instance of Thread class but
before the invocation of start () method.

2. Runnable state-
The thread is in runnable state after invocation of start () method, but
the thread scheduler has not selected it to be the running thread.

3. Running state-
The thread is in running state if the thread scheduler has selected it.

4. Dead state-
A thread is in terminated or dead state when its run () method exits.
5. Waiting state-
When a thread is temporarily inactive, then it’s in one of the
following states: Blocked and Waiting state. Or Running thread calls join
method then it will enter into waiting state (Blocking for joining).

6. Sleep state-
If running thread calls sleep method then it will enter into sleep
state. If sleeping thread got interrupted or time expire then it will enter
into ready state.
7. Waiting state-
If running thread calls wait method then it will enter into waiting
state. If waiting state got notification then it will enter into another wating
state.

8. Suspended state-
If running state called suspend method then thread will enter into
suspended state.

9. Resume state-
If we call thread from resume () method then it will enter into ready
state.

Synchronization in Java-
We can apply synchronization on method and block only. We cannot
apply it on variables and class.
Synchronization means multiple threads is accessing the one resource
at the same time called as. The main purpose of this is we need to ensure that
resource will be used by only one thread at a time. The process by which this is
achieved is called synchronization.

Why?

package [Link];

public class Account {

private int balance=5000;

public int getBalance() {


return balance;
}

public int withdraw(int amount) {


balance= balance-amount;
return balance;
}
}

package [Link];

public class AccountDetails implements Runnable {

Account account = new Account();

@Override
public void run() {

for (int x = 0; x < 5; x++) {

makeWithdrawal(500);

if ([Link]() <= 0) {
[Link]("Account is
overdrawn...");
}
}

private void makeWithdrawal(int amt) {

if ([Link]() >= amt) {

[Link]([Link]().getName()
+
"is going to withdraw=>");
}

try {
[Link](100);
} catch (InterruptedException e) {
[Link]([Link]());
}
int bal = [Link](amt);

[Link]([Link]().getName()
+
"complete the withdrawal=>" + bal);

package [Link];

public class MainTest {

public static void main(String[] args) {

AccountDetails accountDetails= new


AccountDetails();
Thread thread1=new Thread(accountDetails);
Thread thread2= new Thread(accountDetails);
[Link]("Jeevan");
[Link]("soham");
[Link]();
[Link]();
}
}

In this example, there are two thread which are executed randomly but I want to
execute one by one thread at a time then go for synchronization.

Note- Just make the makeWithdrawal method as synchronized, so you will


get the output like as
Output- using synchronization

soham>>is going to withdraw=>


soham>>complete the withdrawal=>4500
soham>>is going to withdraw=>
soham>>complete the withdrawal=>4000
soham>>is going to withdraw=>
soham>>complete the withdrawal=>3500
soham>>is going to withdraw=>
soham>>complete the withdrawal=>3000
soham>>is going to withdraw=>
soham>>complete the withdrawal=>2500
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>2000
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>1500
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>1000
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>500
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>0
Account is overdrawn...

Output- without synchronization

Jeevan>>is going to withdraw=>


soham>>is going to withdraw=>
soham>>complete the withdrawal=>4500
Jeevan>>complete the withdrawal=>4000
soham>>is going to withdraw=>
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>3500
Jeevan>>is going to withdraw=>
soham>>complete the withdrawal=>3000
soham>>is going to withdraw=>
Jeevan>>complete the withdrawal=>2000
soham>>complete the withdrawal=>2500
soham>>is going to withdraw=>
Jeevan>>is going to withdraw=>
Jeevan>>complete the withdrawal=>1500
soham>>complete the withdrawal=>1000
Jeevan>>is going to withdraw=>
soham>>is going to withdraw=>
soham>>complete the withdrawal=>0
Account is overdrawn...
Jeevan>>complete the withdrawal=>500
Account is overdrawn...

Synchronized method-

If you declare any method as synchronized, it is known as synchronized method.

Synchronized method is used to lock an object for any shared resource.

When a thread invokes a synchronized method, it automatically acquires the


lock for that object and releases it when the thread completes its task.

Example- synchronized void test (){


// write code here
}

Synchronized Block-

Synchronized block can be used to perform synchronization on any specific


resource of the method.

Suppose you have 50 lines of code in your method, but you want to synchronize
only 5 lines, you can use synchronized block.

If you put all the codes of the method in the synchronized block, it will work
same as the synchronized method.

Note-

o Synchronized block is used to lock an object for any shared resource.


o Scope of synchronized block is smaller than the method.
Syntax-

synchronized (object reference) {


//code block
}

Common questions

Powered by AI

Challenges with Java threads include race conditions, deadlocks, and resource contention, which occur when threads modify shared resources simultaneously without coordination. Synchronization strategies like using synchronized methods or blocks can alleviate these issues by ensuring mutual exclusion, allowing only one thread to execute critical sections at a time. This prevents race conditions and maintains data integrity. Additionally, proper design of synchronization helps avoid deadlocks by ensuring threads do not indefinitely wait on locks held by each other .

Using synchronized blocks instead of synchronized methods is important when synchronizing only a specific critical section of code rather than the entire method, which can improve performance by reducing the duration a lock is held. This method minimizes blocked threads and resource contention, leading to better parallelism and responsiveness. By locking only essential code blocks, programmers can prevent unnecessary locking of non-critical code, thus enabling other threads to proceed with non-synchronized tasks in parallel .

Without synchronization in a multi-threaded banking application, race conditions can lead to inconsistent account balances as multiple threads may simultaneously modify the balance, causing one thread's updates to overwrite another's. This can result in overdrafts not being detected or incorrect balances being processed, leading to erroneous transactions. Synchronization is crucial to ensure serialized access to the account, preventing multiple threads from executing withdrawal operations at the same time, thus preserving data integrity and transaction correctness .

Waiting and sleep states temporarily suspend a thread’s ability to run, affecting scheduling. A thread enters the waiting state when it calls wait() or join(), ceasing execution until another thread issues a notify() or notifyAll(), or until the thread it is joining completes. A thread in sleep state temporarily halts execution for a specified time, set by the sleep method. Both states prevent the thread from progressing in the workflow until the condition allowing exit to runnable state is met, thus influencing the overall thread management and resource allocation in Java applications .

Java manages thread states through a life cycle that includes new, runnable, running, dead, waiting, sleep, and suspended states. Each state has specific conditions and implications: a thread starts in new state, becomes runnable upon calling start(), and enters the running state when selected by the scheduler. The dead state occurs when the run() method exits. Waiting and sleep states indicate temporary inactivity, with specific methods (wait(), sleep()) determining transitions between these states and the ready/runnable state. Understanding these states is crucial in a multi-threaded environment to ensure resources are accessed efficiently and correctly, avoiding issues like deadlocks or resource contention .

Synchronization in Java locks an object for shared resources, ensuring only one thread accesses the resource at a time, thereby preventing race conditions. When a synchronized method is invoked, a thread automatically acquires the lock and releases it upon task completion. This ensures that no two threads can execute a synchronized method or block on the same object simultaneously, thus preventing inconsistent states or unexpected behavior due to concurrent modifications .

Synchronized methods and blocks impact application performance by introducing locking, which can lead to contention and decreased concurrency when threads block waiting for locks. While they ensure thread safety, excessive use, especially on large sections of code, increases complexity and overhead. Fine-grained synchronization using synchronized blocks rather than methods can minimize these issues by reducing lock scope, thus improving efficiency while maintaining safety. Designers must balance between safety and performance, ensuring minimal blocking while protecting shared resources .

Implementing thread synchronization impacts execution order by serializing the access to shared resources, forcing threads to wait for one another to complete their task with a shared resource before proceeding. In the provided example, synchronizing the makeWithdrawal method ensures that one thread fully completes its withdrawal process before another begins, maintaining deterministic order and consistent outcomes. This prevents interleaved and unpredictable execution which can lead to errors such as incorrect balance updates .

Developers may choose synchronized methods for simplicity and ease of implementation, as they ensure complete method locking without needing to specify block-level synchronization manually. This can be beneficial when the whole method's execution is critical to thread safety. Conversely, synchronized blocks offer more granular control, enabling developers to synchronize only the necessary portion of a method, which can improve efficiency by reducing the lock scope and minimizing thread contention. The choice depends on the specific need for concurrency control and the performance trade-offs involved .

Java's thread lifecycle management contributes to efficient multi-threaded programming by providing a systematic approach to thread creation, execution, and termination. Each state—from new to terminated—directs specific thread actions, ensuring organized scheduling and resource utilization. Efficient state management, including transitions between waiting, blocked, and runnable states, allows for optimized CPU usage, minimal latency, and high throughput. This structured lifecycle prevents chaotic execution, ensuring that resources are not wasted and CPU time is maximized for running important tasks .

You might also like