Each of the method discussed here has some advantages and disadvantages. Here we will see the java.util.concurrent.locks package.
This package has the following main classes.
Explanation:
java.util.concurrent.locks package:
The java API says this packages as, 'Interfaces and classes providing a framework for locking and waiting for conditions that is distinct from built-in synchronization and monitors.'This package has the following main classes.
- AbstractOwnableSynchronizer
- AbstractQueuedLongSynchronizer
- AbstractQueuedSynchronizer
- LockSupport
- ReentrantLock
- ReentrantReadWriteLock
- ReentrantReadWriteLock.ReadLock
- ReentrantReadWriteLock.WriteLock
Example
Remember the race condition example, which we discussed earlier. The same program with ReentrantLock, will solves the race condition. Please see the below code.package thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Sivaranjani D
*
*/
public class AccountOverDraw{
public static void main(String[] args) {
Runnable atm = new ATM();
Thread withdrwer1 = new Thread(atm);
withdrwer1.setName("withdrawer1");
withdrwer1.start();
Thread withdrwer2 = new Thread(atm);
withdrwer2.setName("withdrawer2");
withdrwer2.start();
}
}
class Account {
int balance = 500;
public void debit(int amount) {
balance = balance - amount;
}
public void credit(int amount) {
balance = balance + amount;
}
public int getBalance() {
return balance;
}
}
class ATM implements Runnable {
Account account = new Account();
Lock lock = new ReentrantLock();
public void run() {
for (int i = 0; i <10; i++) {
lock.lock();
if (account.getBalance() > 0) {
makeWithdrawal(100);
} else {
System.out.println("Not enough in amount for "
+ Thread.currentThread().getName() + " to withdraw ");
}
lock.unlock();
}
}
private void makeWithdrawal(int amt) {
if (account.getBalance() >= amt) {
System.out.println(Thread.currentThread().getName()
+ " cheked balance and the balance is :"
+ account.getBalance());
account.debit(amt);
System.out.println(Thread.currentThread().getName()
+ " completes the withdrawal and the balance: "
+ account.getBalance());
}
}
}
Explanation:
- The only difference which avoids race condition is, here the atomic statements are wrapped inside the lock and unlock.
- This step ensures that both the statements can be accessed by only one thread at a time. Also if one thread does balance check it does the debit as well before the other thread reads the balance.
No comments:
Post a Comment