Java--线程通信

采用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唤醒等待的线程。

猜你喜欢

转载自blog.csdn.net/BtWangZhi/article/details/80875901