Mega Code Archive

 
Categories / Java / Threads
 

Using java util concurrent locks Lock to control the synchronized resource

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /*  This program is a part of the companion code for Core Java 8th ed.  (http://horstmann.com/corejava)  This program is free software: you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation, either version 3 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ /**  * This program shows how multiple threads can safely access a data structure.  *   * @version 1.30 2004-08-01  * @author Cay Horstmann  */ public class SynchBankTest {   public static void main(String[] args) {     Bank b = new Bank(NACCOUNTS, INITIAL_BALANCE);     int i;     for (i = 0; i < NACCOUNTS; i++) {       TransferRunnable r = new TransferRunnable(b, i, INITIAL_BALANCE);       Thread t = new Thread(r);       t.start();     }   }   public static final int NACCOUNTS = 100;   public static final double INITIAL_BALANCE = 1000; } /*  * This program is a part of the companion code for Core Java 8th ed.  * (http://horstmann.com/corejava)  *   * This program is free software: you can redistribute it and/or modify it under  * the terms of the GNU General Public License as published by the Free Software  * Foundation, either version 3 of the License, or (at your option) any later  * version.  *   * This program is distributed in the hope that it will be useful, but WITHOUT  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more  * details.  *   * You should have received a copy of the GNU General Public License along with  * this program. If not, see <http://www.gnu.org/licenses/>.  */ /**  * A runnable that transfers money from an account to other accounts in a bank.  *   * @version 1.30 2004-08-01  * @author Cay Horstmann  */ class TransferRunnable implements Runnable {   /**    * Constructs a transfer runnable.    *     * @param b    *          the bank between whose account money is transferred    * @param from    *          the account to transfer money from    * @param max    *          the maximum amount of money in each transfer    */   public TransferRunnable(Bank b, int from, double max) {     bank = b;     fromAccount = from;     maxAmount = max;   }   public void run() {     try {       while (true) {         int toAccount = (int) (bank.size() * Math.random());         double amount = maxAmount * Math.random();         bank.transfer(fromAccount, toAccount, amount);         Thread.sleep((int) (DELAY * Math.random()));       }     } catch (InterruptedException e) {     }   }   private Bank bank;   private int fromAccount;   private double maxAmount;   private int DELAY = 10; } /*  * This program is a part of the companion code for Core Java 8th ed.  * (http://horstmann.com/corejava)  *   * This program is free software: you can redistribute it and/or modify it under  * the terms of the GNU General Public License as published by the Free Software  * Foundation, either version 3 of the License, or (at your option) any later  * version.  *   * This program is distributed in the hope that it will be useful, but WITHOUT  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more  * details.  *   * You should have received a copy of the GNU General Public License along with  * this program. If not, see <http://www.gnu.org/licenses/>.  */ /**  * A bank with a number of bank accounts that uses locks for serializing access.  *   * @version 1.30 2004-08-01  * @author Cay Horstmann  */ class Bank {   /**    * Constructs the bank.    *     * @param n    *          the number of accounts    * @param initialBalance    *          the initial balance for each account    */   public Bank(int n, double initialBalance) {     accounts = new double[n];     for (int i = 0; i < accounts.length; i++)       accounts[i] = initialBalance;     bankLock = new ReentrantLock();     sufficientFunds = bankLock.newCondition();   }   /**    * Transfers money from one account to another.    *     * @param from    *          the account to transfer from    * @param to    *          the account to transfer to    * @param amount    *          the amount to transfer    */   public void transfer(int from, int to, double amount) throws InterruptedException {     bankLock.lock();     try {       while (accounts[from] < amount)         sufficientFunds.await();       System.out.print(Thread.currentThread());       accounts[from] -= amount;       System.out.printf(" %10.2f from %d to %d", amount, from, to);       accounts[to] += amount;       System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());       sufficientFunds.signalAll();     } finally {       bankLock.unlock();     }   }   /**    * Gets the sum of all account balances.    *     * @return the total balance    */   public double getTotalBalance() {     bankLock.lock();     try {       double sum = 0;       for (double a : accounts)         sum += a;       return sum;     } finally {       bankLock.unlock();     }   }   /**    * Gets the number of accounts in the bank.    *     * @return the number of accounts    */   public int size() {     return accounts.length;   }   private final double[] accounts;   private Lock bankLock;   private Condition sufficientFunds; }