package thread.syn; import java.util.Arrays; import java.util.concurrent.locks.ReentrantLock; public class Bank { private final double[] accounts; private ReentrantLock bankLock = new ReentrantLock(); public Bank(int n,double initialBalance){ accounts = new double[n]; Arrays.fill(accounts, initialBalance); } public void transfer(int from ,int to , double amount){ bankLock.lock(); try { if (accounts[from]<amount) { return; } 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("Toal Balance:%10.2f%n",getToalBalance()); } catch (Exception e) { e.printStackTrace(); }finally { bankLock.unlock(); } } public double getToalBalance(){ double sum=0; for(double a: accounts){ sum += a; } return sum; } public int size(){ return accounts.length; } }
package thread.syn; public class TestFour { /** * * * * *14.5.3锁对象 有两种方法阻止受并发访问的干扰 *1.关键字 synchronized * *2.java5引入 ReentrantLock * *每个Bank对象都有自己的ReentrantLock对象,如果两个线程访问同一个Bank对象,将以串行方式访问。 * * 锁是可以重入的,线程可以重复获取已经持有的锁 * * lock() 获取这个锁,如果这个锁被其他的线程持有,将会被阻塞 * * 持有计数:线程有一个持有计数来跟踪对lock方法的嵌套调用,每个lock对应一个unlock,当持有计数为0时,该锁被释放。 * * lock() * unlock() * ReentrantLock( ) */ public static final int NACCOUTS = 100; public static final double INITIAL_BALANCE = 1000; public static final double MAX_AMOUNT = 1000; public static final int DELAY = 10; public static void main(String[] args) { Bank bank = new Bank(NACCOUTS, INITIAL_BALANCE); for (int i = 0; i < NACCOUTS; i++) { int fromAccount = i; Runnable r = () -> { try { while(true){ int toAccount = (int) (bank.size() * Math.random()); double amount = MAX_AMOUNT * Math.random(); bank.transfer(fromAccount, toAccount, amount); Thread.sleep((int) (DELAY*Math.random())); } } catch (Exception e) { e.printStackTrace(); } }; Thread t = new Thread(r); t.start(); } } }