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();
}
}
}