采用Object中的方法模拟存取取钱的操作。只有当存钱后才执行取钱操作。
账户类:
public class Account {
private String accountNo;
private double balance;
/**
* 是否存钱标示
*/
private boolean flag = false;
public Account(String accountNo, double balance) {
this.accountNo = accountNo;
this.balance = balance;
}
/**
* 取钱
*
* @param drawAmount
*/
public synchronized void draw(double drawAmount) {
try {
if (this.flag) {
System.out.println("开始取钱:" + drawAmount);
this.balance -= drawAmount;
this.flag = false;
notifyAll();
} else {
System.out.println("当前无钱,");
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 存钱
*
* @param depositAmount
*/
public synchronized void deposit(double depositAmount) {
try {
if (!this.flag) {
System.out.println("开始存钱" + depositAmount);
this.balance += depositAmount;
this.flag = true;
notifyAll();
} else {
System.out.println("当前已存钱");
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
存钱线程:
public class DepositThread implements Runnable {
private Account account;
private Integer depositAmount;
public DepositThread(Account account, Integer depositAmount) {
this.account = account;
this.depositAmount = depositAmount;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.deposit(this.depositAmount);
}
}
}
取钱线程:
public class DrawThread implements Runnable {
private Account account;
private Integer drawAmount;
public DrawThread(Account account, Integer drawAmount) {
this.account = account;
this.drawAmount = drawAmount;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.draw(this.drawAmount);
}
}
}
启动:
public class TestMain {
public static void main(String[] args) {
Account account = new Account("123456", 0);
new Thread(new DepositThread(account, 800), "存钱者").start();
new Thread(new DrawThread(account, 800), "取钱者").start();
}
}
当执行存钱操作,增加该账户的余额,将是否存钱标示符改为true,同时唤醒该同步锁上的其他线程,存钱操作再次执行,则该线程进入睡眠状态,取钱线程开始执行,减少余额,将是否存钱标示符该为false,唤醒该同步锁上的其他资源。
并发包中的线程类:
public class ReentranLockCondition implements Runnable {
private static ReentrantLock reentrantLock = new ReentrantLock();
private static Condition condition = reentrantLock.newCondition();
@Override
public void run() {
try {
reentrantLock.lock();
condition.await();
System.out.println("Thread is going on");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (reentrantLock.isHeldByCurrentThread()) {
reentrantLock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
ReentranLockCondition reentranLockCondition = new ReentranLockCondition();
Thread thread01 = new Thread(reentranLockCondition);
thread01.start();
Thread.sleep(1000);
// 通知线程继续执行
reentrantLock.lock();
condition.signal();
reentrantLock.unlock();
}
}
执行子线程,调用condition.await()方法让当前线程睡眠,主线程睡眠1秒钟,调用signal唤醒等待的线程。