为什么在等待方法之后的代码没有被调用

问题描述

我有一个使用以下两种方法的客户帐户类,即addBalance和deductBalance。

class CustomerAccount
{
    
    private int balance;
    int getBalance() { return balance;}
    CustomerAccount() {balance=0;}
    boolean deductBalance(final int amount)
    {
        System.out.println("> invoked to deduct :" + amount);
        synchronized (this)
        {
            while (balance <= amount)
            {
                try {wait(); } catch (InterruptedException e) {TestWaitNotifyBasic.logException(e);}
                System.out.println("> hey I was notified for cutting amount:" + amount);
            }
            balance-= amount;
        }
        System.out.println("> deducted:" + amount);
        return true;
    }
    boolean addBalance(final int amount)
    {
        synchronized (this)
        {
            balance += amount;
            notifyAll();
        }
        System.out.println("> balance added: " + amount);
        return true;
    }
}

下面是使用main方法的使用类。想法是让线程等待同步块,直到调用notifyAll。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.IntFunction;



public class TestWaitNotifyBasic
{

    public static void main(String[] args)
    {
        final CustomerAccount chuck = new CustomerAccount();

        IntFunction<Runnable> addBalance = (amount) -> { return () -> chuck.addBalance(amount);};
        IntFunction<Runnable> deductBalance = (amount) -> { return () -> chuck.deductBalance(amount);};

        ExecutorService threadPool = Executors.newFixedThreadPool(100);

        //balance deduction
        threadPool.execute(deductBalance.apply(1000) );
        threadPool.execute(deductBalance.apply(50) );
        threadPool.execute(deductBalance.apply(5000));

        //balance addition
        threadPool.execute(addBalance.apply(900));
        threadPool.execute(addBalance.apply(40));
        threadPool.execute(addBalance.apply(80));
        threadPool.execute(addBalance.apply(8000));

        threadPool.shutdown();
        while (!threadPool.isTerminated())
        {
            try {Thread.sleep(300);} catch (InterruptedException e) {{logException(e);}}
        }
        System.out.println("----------------------" );
        System.out.println("thread operations finished,final balance : " + chuck.getBalance());
        int actualBalance = (900+40+80+8000)-(1000+50+5000);
        System.out.println("Validity check " + actualBalance);
    }

    static void logException(InterruptedException e)
    {
        System.out.println("###########interruptedexception#########" + e);
    }

}

下面是我的控制台输出

> balance added: 80
> invoked to deduct :1000
> balance added: 8000
> invoked to deduct :5000
> invoked to deduct :50
> balance added: 900
> balance added: 40
> deducted:5000
> deducted:50
> deducted:1000
----------------------
thread operations finished,final balance : 2970
Validity check 2970

我的问题是,为什么以下内容未打印在控制台输出

System.out.println(“>嘿,我收到了有关切割量的通知:” +量);

方法写在CustomerAccount类中扣除余额方法的wait()旁边。

解决方法

@RealSkeptic's之后,将addBalance线程修改为在进入执行之前进入休眠状态。发布所有的系统配置文件

上面发布的代码的行为是addBalance线程将在deductBalance线程进入同步块之前执行。

使用下面的addBalance方法,输出会更改。

boolean addBalance(final int amount)
    {
        try {Thread.sleep(3000);} catch (InterruptedException e) {{TestWaitNotifyBasic.logException(e);}}
        synchronized (this)
        {
            balance += amount;
            notifyAll();
        }
        System.out.println("> balance added: " + amount);
        return true;
    }

控制台输出后方法更改:

> invoked to deduct :50
> invoked to deduct :1000
> invoked to deduct :5000
> balance added: 900
> balance added: 40
> hey I was notified for cutting amount:50
> balance added: 8000
> balance added: 80
> hey I was notified for cutting amount:5000
> deducted:50
> hey I was notified for cutting amount:1000
> deducted:1000
> deducted:5000

----------------------
thread operations finished,final balance : 2970
Validity check 2970