java多线程ReenrrantLock用法
来源:互联网 发布:软件分享论坛 app 编辑:程序博客网 时间:2024/05/29 18:59
银行的账号问题,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(); } }}
0 0
- java多线程ReenrrantLock用法
- java 多线程 CountDownLatch用法
- Java多线程的用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- java 多线程 CountDownLatch用法
- Java多线程用法解析
- java 多线程 CountDownLatch用法
- 僵尸对象导致crash(Thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT))
- github之微信签到小程序开坑系列一:开坑
- Retrofit2.0使用总结及注意事项
- 十大著名思想实验
- Ubuntu美化Mac教程
- java多线程ReenrrantLock用法
- 图像风格转换(Image style transfer)
- css设置文本框的属性
- Module
- Android 面试题(二)
- PHP底层的运行机制与原理
- Glide简单使用(二)
- java操作mongodb——查询数据
- SVN服务器搭建和使用(一)