threads
Multiple access example
With this example we are going to demonstrate how to have multiple access over an object. The example describes the transfer of amounts of bank accounts in a bank. In short:
- We have created a class named
SwissBank
. It has a double array called accounts, a Lock calledbankLock
and a Condition calledsufficientFunds
. It has a constructor in which for a specified intn
and a specified doubleinitBalance
, it creates a new accounts array with capacity equal to n, and sets each field of the array to the specified initial balance. It also creates a new ReentrantLock and a new Condition bound to this lock, usingnewCondition()
API method of Lock. In itstransfer(int src, int target, double amount)
method, it aqcuires the lock, usinglock()
API method of Lock and callsawait()
API method of Condition, that causes the current thread to wait until it is signalled or interrupted. After making the transfer of the specified double amount from a source account to the target account of the accounts array, it wakes up all waiting threads, callingsignalAll()
API method of Condition and releases the lock, withunlock()
API method of Lock. In itsgetTotalBalance()
method, it acquires the lock, usinglock()
API method of Lock gets the sum of all fields in the accounts array and then releases the lock, withunlock()
API method of Lock. In itssize()
method it gets the length of the accounts array. - We also have a class named
TransferThread
that implements the Runnable. It has aSwissBank
variable, an intsrcAmmount
, a doublemaxAmount
and an inttimeout
. It overrides therun()
method of the Runnable, where it calls thetransfer()
method of itsSwissBank
object forever, after sleeping for the specified timeout. - We create a new instance of the
SwissBank
with a specified account number and initial balance, and for each one of the accounts we create a newTransferThread
and cause the thread’s execution with its start() API method.
Let’s take a look at the code snippet that follows:
package com.javacodegeeks.snippets.core; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MultipleAccess { public static final int ACCOUNTNUM = 100; public static final double INIT_BALANCE = 1000; public static void main(String[] args) { SwissBank b = new SwissBank(ACCOUNTNUM, INIT_BALANCE); int i; for (i = 0; i < ACCOUNTNUM; i++) { TransferThread tThread = new TransferThread(b, i, INIT_BALANCE); Thread thr = new Thread(tThread); thr.start(); } } } class TransferThread implements Runnable { private SwissBank bank; private int srcAccount; private double maxAmount; private int timeout = 10; public TransferThread(SwissBank b, int src, double amount) { bank = b; srcAccount = src; maxAmount = amount; } @Override public void run() { try { while (true) { int targetAccount = (int) (bank.size() * Math.random()); double cashAmount = maxAmount * Math.random(); bank.transfer(srcAccount, targetAccount, cashAmount); Thread.sleep((int) (timeout * Math.random())); } } catch (InterruptedException ex) { } } } class SwissBank { private final double[] accounts; private Lock bankLock; private Condition sufficientFunds; public SwissBank(int n, double initBalance) { accounts = new double[n]; for (int i = 0; i < accounts.length; i++) { accounts[i] = initBalance; } bankLock = new ReentrantLock(); sufficientFunds = bankLock.newCondition(); } public void transfer(int src, int target, double amount) throws InterruptedException { bankLock.lock(); try { while (accounts[src] < amount) { sufficientFunds.await(); } System.out.print(Thread.currentThread()); accounts[src] -= amount; System.out.printf(" %10.2f from %d to %d", amount, src, target); accounts[target] += amount; System.out.printf(" Total Balance: %10.2f%n", getTotalBalance()); sufficientFunds.signalAll(); } finally { bankLock.unlock(); } } public double getTotalBalance() { bankLock.lock(); try { double am = 0; for (double a : accounts) { am += a; } return am; } finally { bankLock.unlock(); } } public int size() { return accounts.length; } }
This was an example of how to have multiple access over an object in Java.