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