user1003208
user1003208

Reputation: 361

My synchronization doesn't work

I tried to use synchronized and ReentrantLock in Bank.transfer, but i get output like this:

"From 7 to 3 transfered 82.0. Total 918", "From 0 to 4 transfered 27.0. Total 973"

While Total must be equal to 1000. Tell me what am I wrong?

public class expr {
    public static Bank b = new Bank();
    public static void main(String[] args) throws IOException, InterruptedException {
        for (int i = 0; i < 4; i++) {
            new BankTransfer();
        }
    }
}

public class BankTransfer implements Runnable{

    public BankTransfer() {
        Thread t = new Thread(this);
        t.start();
    }

    @Override
    public void run() {

        while (true){
            int from = (int) (expr.b.size * Math.random());
            int to = (int) (expr.b.size * Math.random());
            int amount = (int) (100 * Math.random());
            expr.b.transfer(from, to, amount);

            try {
                Thread.sleep((long) (2000 * Math.random()));
            } catch (InterruptedException e) {
                System.out.println("Thread was interrupted!");
                return;
            }

        }
    }


}

public class Bank {
    private int[] accounts;
    public int size = 10;
    private Lock block = new ReentrantLock();
    public boolean transfer(int from, int to, double amount){
        block.lock();
        try{
            if(accounts[from] >= amount && from != to){
                accounts[from] -= amount;
                System.out.println("From " + from + " to " + to + " transfered " + amount + ". Total " + getTotal());
                accounts[to] += amount;
                return true;
            }
        }finally {
            block.unlock();
        }
        return false;
    }
    public Bank(){
        accounts = new int[size];
        for (int i = 0; i < size; ++i) {
            accounts[i] = 100;
        }
    }
    private int getTotal(){
        int sum = 0;
        for (int i = 0; i < size; ++i) sum += accounts[i];
        return sum;
    }
}

Upvotes: 0

Views: 224

Answers (3)

Daniel
Daniel

Reputation: 10235

You're calling getTotal() after deducting the money from one account, but before adding it to another account. It will always display less than 100, by the amount being transferred.

Upvotes: 1

millimoose
millimoose

Reputation: 39950

This part looks odd:

accounts[from] -= amount;
System.out.println("From " + from + " to " + to + " transfered " + amount + ". Total " + getTotal());
accounts[to] += amount;

You're printing the total before the transfer completes.

Upvotes: 1

wort
wort

Reputation: 136

Calculate the total AFTER you complete both ends of the transfier... i.e. move the System.println after accounts[to] += amount.

Upvotes: 3

Related Questions