Путать с синхронизированным блоком Java - PullRequest
0 голосов
/ 09 октября 2018

В эти дни я читаю книгу Core Java , и я был озадачен, когда прочитал главу о параллелизме.Есть один пример синхронизированного блока, вот сегмент:


[oij]

Мое понимание отмеченного предложения таково: если метод get вектора не синхронизированили я не взламываю блокировку «учетных записей», этот метод передачи не будет потокобезопасным.

Затем я пишу некоторый тестовый код. И я использую другую блокировку без взлома блокировки. Но результат противоположенНасколько я понимаю.

Ниже приведен мой код.

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;
    }
}

тестовый класс:

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();
        }
    }
}

и результат приводит меня в замешательство. Я успешно синхронизировал все потокиобщий баланс всех учетных записей всегда равен 100000.


[awef]

Итак, моя точная проблема в том, что действительно может сделать синхронизированный блок?И что на самом деле означает «взломать замок»?

1 Ответ

0 голосов
/ 09 октября 2018

Мы используем ключевое слово synchronized для предотвращения воздействия нескольких потоков на метод, принадлежащий одному и тому же объекту, на котором действуют потоки.Synchronized в основном используется для предотвращения противоречивых результатов в потоке.Синхронизация задержит выполнение других потоков. Так что ключевое слово synchronized используется только в том случае, если мы хотим, чтобы конкретный метод или блок кода, для которого мы хотим, чтобы одновременно выполнялся только один поток.

...