Can a class be synchronized in java with example

Jasmine 148 Published: 11/26/2024

Can a class be synchronized in java with example

In Java, synchronization is achieved using the synchronized keyword. A class can be synchronized by declaring its methods as synchronized. This ensures that only one thread can execute these methods at a time.

Here's an example of a simple bank account class with synchronized methods:

public class BankAccount {

private int balance;

private final Object lock = new Object();

public BankAccount(int initialBalance) {

this.balance = initialBalance;

}

public void deposit(int amount) {

synchronized (lock) {

try {

Thread.sleep(10); // simulate some work

balance += amount;

System.out.println("Deposited " + amount + ". New balance is " + balance);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

throw new RuntimeException(e);

}

}

}

public void withdraw(int amount) {

synchronized (lock) {

try {

Thread.sleep(10); // simulate some work

if (balance >= amount) {

balance -= amount;

System.out.println("Withdrawn " + amount + ". New balance is " + balance);

} else {

System.out.println("Insufficient funds!");

}

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

throw new RuntimeException(e);

}

}

}

public int getBalance() {

return balance;

}

}

In this example, the BankAccount class has two methods: deposit and withdraw. Both methods are synchronized on a private object lock. This means that only one thread can execute these methods at a time. The use of Thread.sleep(10) simulates some work being done inside each method.

Here's an example of how you could use this class:

public class Main {

public static void main(String[] args) throws InterruptedException {

BankAccount account = new BankAccount(1000);

Thread t1 = new Thread(() -> {

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

account.deposit(50);

}

});

Thread t2 = new Thread(() -> {

for (int i = 0; i < 3; i++) {

account.withdraw(200);

}

});

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("Final balance: " + account.getBalance());

}

}

In this example, we create a BankAccount object and two threads that will deposit and withdraw funds from the account. The deposit and withdraw methods are synchronized to ensure that only one thread can execute them at a time.

This is just a simple example, but it demonstrates how synchronization can be used to protect shared resources in a multi-threaded environment.

How to call synchronized method in Java

I'm sorry! As per the rules, I'll respond in English only.

To call a synchronized method in Java, you can use the following ways:

Method Invocation

You can invoke the synchronized method directly from your code by creating an instance of the class and calling the method on that object. For example:

MyClass obj = new MyClass();

obj.mySynchronizedMethod(); // mySynchronizedMethod is a synchronized method in MyClass

In this case, the JVM will ensure that only one thread can execute this method at any given time, which helps prevent concurrent access issues.

Static Method Invocation

If you have a static synchronized method, you can call it using the class name instead of an instance:

MyClass.myStaticSynchronizedMethod(); // myStaticSynchronizedMethod is a static synchronized method in MyClass

Again, this ensures that only one thread can execute this method at any given time.

Using Synchronization Blocks

You can also use synchronization blocks (synchronized statements) to call the synchronized method. For example:

MyClass obj = new MyClass();

synchronized (obj) {

obj.mySynchronizedMethod(); // mySynchronizedMethod is a synchronized method in MyClass

}

In this case, the JVM will ensure that only one thread can execute the code within the synchronization block at any given time.

Why Synchronization Matters

Synchronization is essential when multiple threads need to access shared resources or modify shared state. Without proper synchronization, your program may encounter issues like:

Data corruption: Multiple threads modifying shared data can lead to inconsistent or incorrect results. Deadlocks: Threads waiting for each other to release locks can cause deadlocks, leading to program termination. Starvation: One thread dominating access to a shared resource while others are starved of opportunities.

By using synchronization mechanisms like synchronized methods and blocks, you can ensure that your Java programs remain safe, predictable, and efficient when dealing with concurrent execution.

Best Practices

When writing synchronized code, keep the following best practices in mind:

Keep synchronization scope minimal: Only synchronize the minimum amount of code necessary to achieve your goal. Avoid unnecessary contention: Ensure that the shared resource is truly being accessed by multiple threads, rather than having a single thread dominate access. Use locks judiciously: Locks can introduce performance overhead; use them only when necessary and avoid deep nesting.

By following these guidelines and using synchronized methods effectively, you'll be well on your way to writing robust, concurrent Java code that handles complex interactions between threads.