Вопрос по синхронизации потоков на Java

160
31 декабря 2019, 22:20

У меня есть класс Res, содержащий синхронизированный метод A и несинхронизированный метод B. В другом классе я создаю экземпляр класса Res и два потока: первому потоку в качестве задачи назначаю выполнение синхронизированного метода A для экземпляра класса Res, а второму потоку назначаю выполнение несинхронизированного метода B для того же экземпляра класса Res. Из литературы я понял, что если синхронизированный метод получает управление, вызывающий поток активирует монитор, который блокирует объект для других потоков, то есть в моем примере сначала должен полностью отработать метод A, а только потом метод B. Однако я проверил и получается, что метод B почему то работает параллельно с методом A. Если я делаю метод B тоже синхронизированным, то эта параллельность пропадает. Получается, что если в одном потоке для объекта вызвался синхронизированный метод, то в другом потоке для этого же объекта может параллельно выполняться несинхронизированный метод? То есть блокируется возможность исполнения для объекта из другого потока только синхронизированных методов, а несинхронизированные методы могут выполняться?

public class Res {
    int number = 0;
    public synchronized void A(){
        for (int i = 0; i<10000; i++) {
            number += 1;
            System.out.println(number);
        }
    }
    public void B(){
        for (int i = 0; i <10000; i++)
        number-=1;
        }
    }
public class Threads {
    Res commonRes = new Res();
    public void startThreads(){
        new Thread(()->commonRes.A()).start();
        new Thread(()-> commonRes.B()).start();
    }
}
Answer 1

Несинхронизированным методам монитор не нужен (если конечно внутри этого метода нет захвата монитора через synchronized(...)). Когда Вы пишете нестатические синхронизированные методы, то они перед выполнением захватывают монитор текущего экземпляра. Именно, так сказать, не текущий экземпляр - а его монитор. Поэтому другие несинхронизированные нестатические методы могут работать спокойно из любого потока - им монитор не нужен. В случае статических синхронизированных методов будет захват монитора уже не экземпляра класса, а у самого класса. В больших приложениях если Вы хотите, чтобы монитор захватывался только вашим кодом, нужно создавать специальный не доступный другому коду объект, монитор которого ваши потоки будут захватывать.

READ ALSO
Как поправить transition эффект?

Как поправить transition эффект?

Очень нравится выпадающее меню в теме ColorNews (демо сайт)Меню я из этой темы позаимствовал, встроил на свой сайт, однако выяснилась проблема...

191
javascript canvas: изображение не выводится

javascript canvas: изображение не выводится

Подскажите, почему при таком коде:

194
Удаление элемента из массива javascript

Удаление элемента из массива javascript

Нужна функция removeArray(x, n), которая удаляет n из массива и извлекает полученный элементНапример:

185
Как отключить перенос строк в vscode для javascript и html

Как отключить перенос строк в vscode для javascript и html

Правлю код vuejs компонента в vscode, при этом периодически жму Alt + Shift + F для автоматического форматирования введённого кода

256