首页 > 编程 > Java > 正文

java多线程ReenrrantLock用法

2019-11-08 01:17:21
字体:
来源:转载
供稿:网友

银行的账号问题,100个账户,每个账户拥有1000¥。各个账户之间来回转账,但是总的转账金额不变

使用锁,就不能使用带资源的try语句。当条件对象调用了await()方法后,该线程处于等待状态,必须等待另一个线程调用singalAll()方法唤醒该线程,唤醒时该线程处于阻塞状态。signal随机解除等待状态中的某个线程。package test2;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class Bank { PRivate final double[] accounts; private Lock bankLock; //锁对象 private Condition sufficientFunds; //条件对象,用来表达是否是余额充足 public Bank(int n, double initialBance) { accounts = new double[n]; for (int i = 0; i < accounts.length; i++) { accounts[i] = initialBance; } bankLock = new ReentrantLock(); sufficientFunds = bankLock.newCondition(); } public void transfer(int from, int to, double amount) { /* 确保任意时刻只有一个线程进入临界区。*/ bankLock.lock(); try { /*判断余额是否充足,入宫不充足,则线程进入等待状态。*/ while (accounts[from] < amount) { /* * 等待获得锁的线程和调用await方法的线程存在本质的不同。 * 一旦一个线程调用await方法,它进入该条件的等待集。 * 当锁可以用时,该线程不能马上解除阻塞。相反,它处于阻塞状态,直到另一个线程 * 调用同一个条件上的singalAll方法时为止 */ sufficientFunds.wait(); } System.out.println(Thread.currentThread()); accounts[from] -= amount; System.out.printf("%10.2f from %d to %d ", amount, from, to); accounts[to] +=amount; System.out.printf("Total Blance: %10.2f %n", getTotalBalance()); sufficientFunds.signalAll(); } catch (Exception e) { //e.printStackTrace(); } finally { /* 临界区抛出异常,但是要把锁释放掉,否则其他线程将永远阻塞。*/ bankLock.unlock(); } } public double getTotalBalance() { bankLock.lock(); try { double sum = 0; for ( double a : accounts) { sum += a; } return sum; } catch (Exception e) { e.printStackTrace(); return 0.00; } finally { bankLock.unlock(); } } public int size() { return accounts.length; }}package test2;public class TransferRunnable implements Runnable{ private Bank bank; private int fromAccount; private double maxAmount; private int DELAY = 10; public TransferRunnable(Bank bank, int fromAccount, double maxAmount) { this.bank = bank; this.fromAccount = fromAccount; this.maxAmount = maxAmount; } @Override 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 (Exception e) { e.printStackTrace(); } }}package test2;public class UnsynchBankTest { public static final int NACCOUNTS = 100; public static final double INITIAL_BALANCE = 1000; public static void main(String[] args) { Bank b = new Bank(NACCOUNTS, INITIAL_BALANCE); for (int i = 0; i < NACCOUNTS; i++) { TransferRunnable r = new TransferRunnable(b, i, INITIAL_BALANCE); Thread t = new Thread(r); t.start(); } }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表