-1

These days, I am reading the book Core Java and I was confused when I read Concurrency Chapter. There is one example of the synchronized block, here is the segment:


[oij]

My understanding of the marked sentence is that If the get method of Vector is not synchronized or I don't hijack the lock of 'accounts', this transfer method will not be thread safe.

Then I write some test code.And I use another lock without hijacking the lock.But the result is opposite of my understanding.

The following is my code.

public class VectorBank {
    public void transfer(Vector<Integer> accounts, int from, int to, Integer amount) {
        synchronized (this) {
            if (accounts.get(from) < amount) return;
            accounts.set(from, accounts.get(from) - amount);
            accounts.set(to, accounts.get(to) + amount);
            System.out.println(getTotalBanlance(accounts));
        }
    }

    public Integer getTotalBanlance(Vector<Integer> accounts) {
        Integer sum = new Integer(0);
        for (Integer a : accounts) {
            sum += a;
        }
        return sum;
    }
}

the test class:

public class VectorBankTest {
    public static final int MAX_AMOUNT = 1000;
    public static final int DELAY = 10;
    public static final int NACCOUNTS = 100;
    public static final int INITIAL_BALANCE = 1000;

    public static void main(String[] args) {
        Vector<Integer> accounts = new Vector<>();
        for (int i = 0; i < NACCOUNTS; i++) {
            accounts.add(INITIAL_BALANCE);
        }
        VectorBank bank = new VectorBank();
        for (int i = 0; i < NACCOUNTS; i++) {
            int fromAccount = i;
            Runnable r = () -> {
                try {
                    while (true) {
                        int toAccount = (int) (accounts.size() * Math.random());
                        int amount = (int) (MAX_AMOUNT * Math.random() + 1);
                        bank.transfer(accounts, fromAccount, toAccount, amount);
                        Thread.sleep((int) (DELAY * Math.random()));
                    }
                } catch (InterruptedException e) {
                    System.out.println("Do nothing!");
                }
            };
            Thread t = new Thread(r);
            t.start();
        }
    }
}

and the result make me confused.I synchronized all thread successfully, the total banlance of all accounts is always 100000.


[awef]

So my exact problem is, what indeed can a synchronized block do? And what does 'hijack a lock' really mean?

Nic3500
  • 8,144
  • 10
  • 29
  • 40
  • there is only one thread try adding multiple thread with and without synchronized block only then synchronized will make sense – Pushkarraj Pujari Oct 09 '18 at 04:54
  • sorry, I can't understand what's you say.what do you mean one thread try adding multiple thread with? – Khirye Zhou Oct 09 '18 at 05:24
  • I think you're right. It's sometimes necessary to "hijack" the lock to prevent modification during a sensitive operation, e.g., to prevent a CME while iterating. But this example doesn't demonstrate that. Any shared lock would suffice here. – shmosel Oct 09 '18 at 05:26
  • Possible duplicate of [Is there an advantage to use a Synchronized Method instead of a Synchronized Block?](https://stackoverflow.com/questions/574240/is-there-an-advantage-to-use-a-synchronized-method-instead-of-a-synchronized-blo) – karan shah Oct 09 '18 at 05:29
  • Everything happens inside one lock so you have single threaded all the critical code, move the print of total outside the lock and remove the sleep. – Peter Lawrey Oct 09 '18 at 07:41

1 Answers1

-1

We use synchronized keyword to prevent multiple threads to act on a method which belong to the same object on which threads are acting. Synchronized is mainly used to prevent the inconsistent results from the thread. Synchronization will delay the execution of other threads.So synchronized keyword is used only we want the particular method or a block of code on which we want only one thread should execute at a time.

Siddu
  • 156
  • 7