Вопрос по java – Синхронизация, когда использовать или не использовать?

13

Я начал изучать параллелизм и потоки в Java. Я знаю основы синхронизированных (то есть что он делает). Концептуально я понимаю, что он обеспечивает взаимоисключающий доступ к общему ресурсу с несколькими потоками в Java. Но когда я сталкиваюсь с примером, подобным приведенному ниже, я не могу понять, стоит ли синхронизировать его. Я знаю, что критические разделы кода должны быть синхронизированы, и это ключевое слово не должно использоваться чрезмерно, или это влияет на производительность.

public static synchronized List<AClass> sortA(AClass[] aArray) 
{
    List<AClass> aObj = getList(aArray);

    Collections.sort(aObj, new AComparator());

    return aObj;
}

public static synchronized List<AClass> getList(AClass[] anArray) 
{
    //It converts an array to a list and returns
}
Синхронизация не требуется, потому что ваши методы не сохраняют состояния. Luca

Ваш Ответ

5   ответов
11

a different array тогда никакая синхронизация не требуется, потому что остальные переменные являются локальными.

Если вместо этого вы запустите несколько потоков, все вызовыsortA и передать ссылку на тот же массив,you'd be in trouble безsynchronizedпотому что они будут мешать друг другу.

Остерегайтесь, что из примера может показаться, чтоgetList метод возвращает новыйList из массива, так что даже если потоки проходят один и тот же массив, вы получаете разныеList объекты. Это вводит в заблуждение. Например, используяArrays.asList создаетList поддержанный данным массивом, но Javadoc ясно заявляет, чтоChanges to the returned list "write through" to the array. так что будь осторожен с этим.

2

как вы правильно поняли, влияет на пропускную способность вашего приложения, а также может привести к истощению потоков.

Все get в основном должны быть не блокирующими, как реализовано в Collections in concurrency package.

Как в вашем примере все вызывающие потоки передадут туда свою копию массива,getList не нужно синхронизировать, поэтомуsortA Метод, как и все остальные переменные являются локальными.

Локальные переменные живут в стеке, и каждый поток имеет свой собственный стек, поэтому другие потоки не могут ему помешать.

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

2

поэтому их не нужно синхронизировать.

2

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

5

когда вы разделяете данные между несколькими вызовами, и существует вероятность того, что данные будут изменены, что приведет к несогласованности. Если данные доступны только для чтения, синхронизация не требуется.

В приведенном выше фрагменте кода нет данных для обмена. Методы работают с предоставленным вводом и возвращают вывод. Если несколько потоков вызывают один из ваших методов, каждый вызов будет иметь свой собственный ввод и вывод. Следовательно, нет никаких шансов непоследовательности нигде. Таким образом, ваши методы в приведенном выше фрагменте не должны быть синхронизированы.

Синхронизация, если она используется излишне, наверняка приведет к снижению производительности из-за задействованных накладных расходов и, следовательно, должна использоваться с осторожностью только при необходимости.

Синхронизация статического метода в приведенном выше фрагменте для обеспечения функциональности, которую он предоставляет, не является правильной. Пользователи должны остерегаться сценария, который вы упомянули извне, везде, где это необходимо
Откуда вы знаете, что никакие данные не передаются? Потоки могут передавать один и тот же массивsortA метод.
Вполне возможно! Ну, в этом случае вам обязательно нужно синхронизировать. Дело в том, что пользователи кода должны знать, является ли ваш код потокобезопасным или нет. Как разработчик, вы знаете, должен ли ваш код быть поточно-ориентированным или нет. Если нет, то вам нужно документировать это для пользователей, чтобы они могли явно синхронизироваться в интересных сценариях. Вам не нужно синхронизировать все в вашем коде.

Похожие вопросы