Category : Java | Sub Category : Java Threads | By Prasad Bonam Last updated: 2023-08-16 08:28:27 Viewed : 45
In Java, you can use object-level locks (also known as instance-level locks) and class-level locks to achieve synchronization and manage access to shared resources among multiple threads. Lets explore both concepts with examples and outputs.
Object-level locks are associated with individual instances of objects. They ensure that only one thread can execute a synchronized block of code on a specific instance at a time. Here is an example using object-level locks:
javapublic class ObjectLockExample {
private int count = 0;
public void increment() {
synchronized (this) {
count++;
}
}
public int getCount() {
synchronized (this) {
return count;
}
}
}
public class ObjectLockThread extends Thread {
private ObjectLockExample example;
public ObjectLockThread(ObjectLockExample example) {
this.example = example;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
example.increment();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
ObjectLockExample example = new ObjectLockExample();
ObjectLockThread thread1 = new ObjectLockThread(example);
ObjectLockThread thread2 = new ObjectLockThread(example);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final count: " + example.getCount());
}
}
Output:
yamlFinal count: 2000
In this example, the synchronized
blocks within the increment()
and getCount()
methods use the this
reference as the lock. This ensures that only one thread can execute those blocks for the same instance of ObjectLockExample
.
Class-level locks, sometimes called static locks, are associated with the class itself rather than individual instances. They ensure that only one thread can execute synchronized blocks of code within static methods on the class. Here is an example using class-level locks:
javapublic class ClassLockExample {
private static int count = 0;
public static void increment() {
synchronized (ClassLockExample.class) {
count++;
}
}
public static int getCount() {
synchronized (ClassLockExample.class) {
return count;
}
}
}
public class ClassLockThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
ClassLockExample.increment();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
ClassLockThread thread1 = new ClassLockThread();
ClassLockThread thread2 = new ClassLockThread();
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final count: " + ClassLockExample.getCount());
}
}
Output:
yamlFinal count: 2000
In this example, the synchronized
blocks within the increment()
and getCount()
methods use ClassLockExample.class
as the lock. This ensures that only one thread can execute those blocks at a time, regardless of which instance of ClassLockExample
is used.
Both object-level locks and class-level locks are essential for managing thread safety in multi-threaded applications. The choice between them depends on whether you need synchronization at the instance level or the class level.