进程协调运行的两种方式

使用显示lock锁

使用隐式sychronized的加锁

account类

package newThread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Account {
    private String accountNo;
    private double balance;
    private boolean flag=false;
    public Account() {
        super();
    }
    public Account(String accountNo, double balance) {
        super();
        this.accountNo = accountNo;
        this.balance = balance;
    }
    public String getAccountNo() {
        return accountNo;
    }
    public void setAccountNo(String accountNo) {
        this.accountNo = accountNo;
    }
    public double getBalance() {
        return balance;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }
    @Override
    public int hashCode() {
        return accountNo.hashCode();
        //返回对象的编码
    }
    @Override
    public boolean equals(Object obj) {
        if(obj!=null&&obj.getClass()==Account.class) {
            Account target=(Account) obj;
            return target.getAccountNo().equals(accountNo);
        }
        return false;
    }
    private final Lock lock=new ReentrantLock();
    private final Condition cond=lock.newCondition();
    //①public synchronized void draw(double drawAmount);

    public  void draw(double drawAmount) {
        lock.lock();    //②使用lock锁和condition类实现同步
        try {
                if(!flag) {
                    cond.await();//wait()
                }else {
                    System.out.println(Thread.currentThread().getName()+"取钱"+drawAmount);
                    balance-=drawAmount;
                    System.out.println("账户余额:"+balance);
                    flag=false;
                    cond.signalAll();//唤醒其它线程notifyAll();
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
    }
    public synchronized void deposit(double depositAmount) {
        lock.lock();
        try {
            if(flag) {
                cond.await();
            }else {
                System.out.println(Thread.currentThread().getName()+"存钱"+depositAmount);
                balance+=depositAmount;
                System.out.println("账户余额:"+balance);
                flag=true;
                cond.signalAll();//唤醒其它线程
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
}
}

线程类

package newThread;

public class DepositThread extends Thread {
    private Account account;//模拟用户账户
    private double depositAmount;


    public DepositThread(String name, Account account, double depositAmount) {
        super(name);
        this.account = account;
        this.depositAmount = depositAmount;
    }


    @Override
    public void run() {
        for(int i=0;i<100;i++) {
            account.deposit(depositAmount);
        }
    }
}
package newThread;

public class DrawThread extends Thread {
    private Account account;//模拟用户账户
    private double drawAmount;

    public DrawThread(String name, Account account, double drawAmount) {
        super(name);
        this.account = account;
        this.drawAmount = drawAmount;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++) {
            account.draw(drawAmount);
        }
    }


}

测试类

package newThread;

public class TestDraw {

    public static void main(String[] args) {
        Account acct=new Account("123456780",0);
        new DrawThread("取钱",acct,800).start();
        new DepositThread("存款者甲",acct,800).start();
        new DepositThread("存款者乙",acct,800).start();
        new DepositThread("存款者丙",acct,800).start();

    }

}

运行结果这里写图片描述

注意要先运行存钱线程然后才能实现取钱线程

猜你喜欢

转载自blog.csdn.net/qq_26391203/article/details/75327169