Разница между замками и синхронизированными методами

Я понимаю, что синхронизация допускает неявные блокировки, но разве они не дают одинаковых результатов?

В чем разница между следующими двумя разделами кода? Почему программист решил использовать каждый?

Блок кода № 1

class PiggyBank {    
    private int balance = 0; 
    public int getBalance() {
        return balance; 
    }
    public synchronized void deposit(int amount) { 
        int newBalance = balance + amount;
        try {
            Thread.sleep(1);
        } catch (InterruptedException ie) {
            System.out.println("IE: " + ie.getMessage());
        }
        balance = newBalance;
    }
}

Блок кода № 2

class PiggyBank {
    private int balance = 0;
    private Lock lock = new ReentrantLock(); 

    public int getBalance() {
        return balance; 
    }
    public void deposit(int amount) { 
        lock.lock();
        try {
            int newBalance = balance + amount; 
            Thread.sleep(1);
            balance = newBalance;
        } catch (InterruptedException ie) { System.out.println("IE: " + ie.getMessage());
        } finally { 
            lock.unlock();
        } 
    }
}

1 ответ

Решение

Оба ваших примера, которые вы предоставили, будут служить одной и той же цели, и они равны с точки зрения поточной безопасности (я бы также изменил ваш баланс). ReentrantLock более "неструктурирован", это означает, что вы можете заблокировать критическую секцию в одном методе и разблокировать ее в другом методе; что-то, что вы не можете сделать с синхронизированным, потому что это структура в блоке.

Есть также проблема с производительностью, когда вы хотите использовать ReentrantLock поверх синхронизированного, но это верно только при использовании нескольких потоков.

Другие вопросы по тегам