I have a customer account class with below 2 methods, addBalance and 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;
}
}
Below is the consuming class with main method. The idea is to have threads wait for synchronized block until notifyAll is called.
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);
}
}
Below is my console output
> 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
The question I have is, why the below is not printed in console output
System.out.println("> hey I was notified for cutting amount:" + amount);
This method is written next to wait() of deduct balance method in CustomerAccount class.