Подтвердить что ты не робот

Java два синхронизированных метода в одном экземпляре

рассмотрим следующий код:

public class SynchronizedCounter extends Thread {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public void run() {
        for(;;)
            increment();
    }
}

static void main(String[] args) {
    SynchronizedCounter counter = new SynchronizedCounter();
    counter.start();
    for(;;)
        counter.decrement();
}

означает ли это, что методы increment() и decment() будут ждать друг друга до конца или нет?

EDIT: и это не ждет?

static void main(String[] args) {
    SynchronizedCounter counter1 = new SynchronizedCounter();
    SynchronizedCounter counter2 = new SynchronizedCounter();
    counter1.start();
    for(;;)
        counter2.decrement();
}
4b9b3361

Ответ 1

Да, ключевое слово synchronized является сокращением для:

synchronized(this) {
  //...
}

Таким образом, оба метода эффективно блокируются на одном и том же объекте mutex. Если вы хотите, чтобы они были независимыми друг от друга (что плохой идеей в этом примере, поскольку оба они имеют одинаковое значение), см. Объект блокировки частных членов класса - лучшая практика? (Java).

Кстати, ваш SynchronizedCounter должен реализовывать Runnable, а не расширять Thread, поскольку вы передаете его другому конструктору потока - теперь он немного запутан.

Ответ 2

Блокировка всегда находится на всем объекте. Если какой-либо из них получает доступ к элементам synchronized.

В вашем первом примере есть два потока , конкурирующих за тот же counter объект, тот, который вы начали явно (который вызывает метод increment() в бесконечном цикле), а другой поток основной поток (который бесконечно вызывает decrement()).

Во втором примере создаются два объекта counter1 и counter2. Они будут иметь свои собственные блокировки независимо друг от друга. Блокировка одного объекта не влияет на другие потоки от доступа к другому объекту. Два потока (явный и основной поток) получают блокировку на двух разных объектах и, следовательно, в без конкуренции.

Ответ 3

означает ли это, что методы increment() и decment() будут ждать друг друга до конца или нет?

НЕТ, это означает, что ни один другой поток не сможет вызывать increment() и decment(), когда один поток находится внутри них. Чтобы быть полным, другой поток не смог выполнить какой-либо синхронизированный метод этого экземпляра/объекта

Вы можете вызвать любой другой синхронизированный метод из синхронизированного без блокировки на том же экземпляре/объекте