线程间协作

一个线程可以指定在某种条件下该做什么。条件是通过调用Lock对象的newCondition()方法而创建的对象。一旦创建了条件,就可以使用await()、signal()和signalAll()方法来实现线程间的互相通信。await()方法可以让当前线程都处于等待状态,直到条件发生。signal()方法唤醒一个等待的线程,而signalAll()方法唤醒所有等待的线程。

例:两个线程同时运行一下两个方法

private static Lock lock = new ReentrantLock();
private static Condition newDeposit = lock.newCondition();
private int balance = 0;

public void withDraw(int amount){
    lock.lock();
    try{
        while(balance < amount){
            System.out.println("\t\t\tWait for a deposit");
            newDeposit.await();
        }
        balance -= amount;
        System.out.println("\t\t\tWithDraw " + amount + "\t\t" + getBalance());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }finally {
        lock.unlock();
    }
}

public void deposit(int amount){
    lock.lock();
    try{
        balance += amount;
        System.out.println("Deposit " + amount + "\t\t\t\t\t" + getBalance());
        newDeposit.signalAll();
    }finally {
        lock.unlock();
    }
}

可以看出,当balance的值小于amount时会调用await()方法进入等待状态,直到deposit方法中调用了signalAll()方法,withDraw方法才继续执行。

为了判断调用signalAll()方法后是从withDraw()方法的什么地方开始重新执行这个问题,在进入withDraw()方法后的第一行加入输出一条判断语句

public void withDraw(int amount){
    System.out.println("---------Method withDraw run---------");
    lock.lock();
    try{
        while(balance < amount){
            System.out.println("\t\t\tWait for a deposit");
            newDeposit.await();
        }
        balance -= amount;
        System.out.println("\t\t\tWithDraw " + amount + "\t\t" + getBalance());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }finally {
        lock.unlock();
    }
}

 重新运行程序

可以看出balance-amount之后重新调用一次withDraw方法进行下一次减数,balance小于amount后等待deposit方法,deposit方法中signalAll()唤醒withDraw之后并没有从方法的第一行开始执行,直接输出了Wait for a deposition,等待deposition方法,由此可知调用signalAll()方法后将从await()方法开始继续执行之后的逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值