package com.yli.thread.lock;
/**
* 不加锁,在两个账户之间转账,多次运行会发现两个账号的总额由变化
*
* @author yli
*
*/
public class UnLockTest {
public static final int TOTAL_AMOUNT = 100000;
public static void main(String[] args) {
Bank1 bank = new Bank1("yli", 100000);
Bank1 targetBank = new Bank1("ylz", 0);
System.out.println(Thread.currentThread().getName() + "=========>总额="
+ (bank.getBalance() + targetBank.getBalance()));
for (int i = 0; i < 20000; i++) {
TransferBank1 transfer = new TransferBank1(bank, targetBank, 5);
Thread thread = new Thread(transfer);
thread.setName("Transfer-" + i);
thread.start();
}
}
}
class TransferBank1 implements Runnable {
private Bank1 bank;
private Bank1 targetBank;
private int amount;
public TransferBank1(Bank1 bank, Bank1 targetBank, int amount) {
this.bank = bank;
this.targetBank = targetBank;
this.amount = amount;
}
@Override
public void run() {
this.bank.transferAccount(targetBank, amount);
}
}
class Bank1 {
private String name;
private int balance;
public Bank1(String name, int balance) {
this.name = name;
this.balance = balance;
}
public void transferAccount(Bank1 targetBank, int amount) {
this.balance -= amount;
targetBank.balance += amount;
int total = this.getBalance() + targetBank.getBalance();
System.out.println(Thread.currentThread().getName() + "=========>总额=" + total);
if (total != UnLockTest.TOTAL_AMOUNT) {
Thread.currentThread().interrupt();
try {
throw new InterruptedException("================>转账错误,抛出异常");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
}
================================华丽丽的分割线=====================================
package com.yli.thread.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 加锁,两个账户之间转账没有影响
* @author yli
*
*/
public class ReentLockTest {
public static final int TOTAL_AMOUNT = 100000;
public static void main(String[] args) {
Bank bank = new Bank("yli", TOTAL_AMOUNT);
Bank targetBank = new Bank("ylz", 0);
System.out.println(Thread.currentThread().getName() + "=========>总额=" + (bank.getBalance() + targetBank.getBalance()));
for (int i = 0; i < 20000; i++) {
TransferBank transfer = new TransferBank(bank, targetBank, 5);
Thread thread = new Thread(transfer);
thread.setName("Transfer-" + i);
thread.start();
}
}
}
class TransferBank implements Runnable {
private Bank bank;
private Bank targetBank;
private int amount;
public TransferBank(Bank bank, Bank targetBank, int amount) {
this.bank = bank;
this.targetBank = targetBank;
this.amount = amount;
}
@Override
public void run() {
this.bank.transferAccount(targetBank, amount);
}
}
class Bank {
private String name;
private int balance;
private Lock transferLock;
private Condition transferCon;
public Bank(String name, int balance) {
this.name = name;
this.balance = balance;
this.transferLock = new ReentrantLock();
this.transferCon = this.transferLock.newCondition();
}
public void transferAccount(Bank targetBank, int amount) {
this.transferLock.lock();
try {
while (this.balance < amount) {
this.transferCon.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
this.balance -= amount;
targetBank.balance += amount;
int total = this.getBalance() + targetBank.getBalance();
System.out.println(Thread.currentThread().getName() + "=========>总额=" + total);
if(total != ReentLockTest.TOTAL_AMOUNT){
Thread.currentThread().interrupt();
try {
throw new InterruptedException("================>转账错误,停止运行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.transferCon.signalAll();
this.transferLock.unlock();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getBalance() {
this.transferLock.lock();
try {
return balance;
} finally {
this.transferLock.unlock();
}
}
public void setBalance(int balance) {
this.balance = balance;
}
}