0

takeAmount and addAmount is simply to add/sub value from balanceAccount(eg. add 11,12...,20 or add 101,102...,110). balanceAccount have two version one is using synchronized function and other is using synchronized block.

Is that any different between BalanceAccount_synchronizedBlock and BalanceAccount_synchronizedFunction?

Indeed BalanceAccount_synchronizedFunction always return 0, while BalanceAccount_synchronizedBlock doesn't.

And...why it will show different behavior?

public class mainStart {
    public static void main(String args[]) 
    {
        for (int i=1;i<3000;i=i+10)
        {
            new Thread(new addAmount(i)).start();
            new Thread(new takeAmount(i)).start();
        }

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //BalanceAccount_synchronizedBlock.printAmount();
        BalanceAccount_synchronizedFunction.printAmount();
    }


}

class takeAmount implements Runnable {
    private int startFrom;

    public takeAmount(int start)
    {
        this.startFrom=start;
    }

    public void run() 
    {   
        for (int i=startFrom;i<startFrom+10;i++)
            //BalanceAccount_synchronizedBlock.sub(i);
            BalanceAccount_synchronizedFunction.sub(i);
    }

}

class addAmount implements Runnable {
    private int startFrom;

    public addAmount(int start)
    {
        this.startFrom=start;
    }

    public void run() 
    {   
        for (int i=startFrom;i<startFrom+10;i++)
            //BalanceAccount_synchronizedBlock.add(i);
            BalanceAccount_synchronizedFunction.add(i);
    }

}

public class BalanceAccount_synchronizedBlock {
    public static Integer amount=0;

    public static void add(int a)
    {
        synchronized (amount)
        {
            amount = amount + a;
        }
    }

    public static void sub(int a)
    {
        synchronized (amount)
        {
            amount = amount - a;
        }
    }

    public synchronized static void printAmount()
    {
        System.out.println("Amount " + amount);
    }

}

public class BalanceAccount_synchronizedFunction {
    public static Integer amount=0;

    public synchronized static void add(int a)
    {
            amount = amount + a;
    }

    public synchronized static void sub(int a)
    {
            amount = amount - a;
    }

    public synchronized static void printAmount()
    {
        System.out.println("Amount " + amount);
    }

}

3 Answers3

2

Synchronizing a method uses the enclosing class as a synchronization token. When you write synchronized(amount) you are using an Integer instance as a synchronization token. As you are not using the same token in both cases, the lock will not occur as expected.

Also note that Integer is immutable, and every time you reassign a value into amount, you are creating a new instance an lose whatever lock you may have had on the previous value.

dotvav
  • 2,808
  • 15
  • 31
0

Your print method is defined as

public synchronized static void printAmount()

which is synchronized on the class itself. In the case of your "block" attempt, the blocks are synchronizing on amount, while the print method is synchronizing on the class. Change that method to use a block also synchronized on amount.

As Kayaman pointed out, you also have the problem that you're synchronizing on a variable (amount) whose referent is constantly changing. Instead, declare a private static final Object LOCK = new Object() that is used only for synchronization--or better yet, just use AtomicInteger.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
0

You can either lock using object which is calling this method by using

synchronized (this) { // this is similar to method level synchronization

Or using another class level Object other then amount integer(as @Kayaman pointed out, it is immutable so every time new integer object is created when you update it)

public class BalanceAccount_synchronizedBlock {
    public static Integer amount=0;
    public static Object Lock = new Object();

    public static void add(int a) {
        synchronized (Lock) {
            amount = amount + a;
        }
    }
Naman Gala
  • 4,670
  • 1
  • 21
  • 55