Reputation: 570
I have a method which looks like the below.
public class CriticalSections
{
public void mainMethod(boolean b)
{
if (b) {
method1();
}
else {
criticalMethod();
method2();
}
}
private void criticalMethod()
{
System.out.println("in criticalMethod");
}
private void method1()
{
System.out.println("in method1");
}
private void method2()
{
System.out.println("in method2");
}
}
I need to restrict access to these methods such that
In order to satisfy the 1st access condition I came up with the following code, but this would not satisfy the other 3 conditions and therefore performance will take a hit.
public class CriticalSections
{
private final Lock lock1 = new ReentrantLock();
private final Lock lock2 = new ReentrantLock();
private final Lock lock3 = new ReentrantLock();
public void mainMethod(boolean b)
{
if (b) {
lock1.tryLock();
try {
method1();
}
finally {
lock1.unlock();
}
}
else {
lock1.tryLock();
try {
lock2.tryLock();
try {
lock3.tryLock();
try {
criticalMethod();
}
finally {
lock3.unlock();
}
}
finally {
lock2.unlock();
}
}
finally {
lock1.unlock();
}
}
lock3.tryLock();
try {
method2();
}
finally {
lock3.unlock();
}
}
private void criticalMethod()
{
System.out.println("in criticalMethod");
}
private void method1()
{
System.out.println("in method1");
}
private void method2()
{
System.out.println("in method2");
}
}
What should be the synchronization mechanism to be used for satisfying the scenarios mentioned?
Upvotes: 1
Views: 173
Reputation: 1535
What you need is an exclusive lock on criticalMethod
and shareable locks on methods method1
and method2
. The simplest way to achieve this is to use java.util.concurrent.locks.ReentrantReadWriteLock
as below:
public class CriticalSections {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void mainMethod(boolean b) {
if (b) {
method1();
} else {
criticalMethod();
method2();
}
}
private void criticalMethod() {
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
System.out.println("in criticalMethod");
} finally {
writeLock.unlock();
}
}
private void method1() {
Lock readLock = lock.readLock();
readLock.lock();
try {
System.out.println("in method1");
} finally {
readLock.unlock();
}
}
private void method2() {
Lock readLock = lock.readLock();
readLock.lock();
try {
System.out.println("in method2");
} finally {
readLock.unlock();
}
}
}
If you're worried about performance, you can also take a look at java.util.concurrent.locks.StampedLock
(Java 8+).
Upvotes: 3