Upadte: с момента написания ниже, я вижу, вы немного обновили вопрос. Простите мое невежество - я понятия не имею, что такое «аспект», - но из примера кода, который вы опубликовали, вы также можете рассмотреть возможность использования атомарных / параллельных коллекций (например, AtomicInteger, AtomicIntegerArray) или средства обновления атомных полей, Впрочем, это может означать ре-факторинг вашего кода. (В Java 5 на гиперпоточном Xeon с двумя процессами пропускная способность для AtomicIntegerArray значительно лучше, чем для синхронизированного массива; извините, я еще не успел повторить тест на более поздней версии JVM для procs / более поздней версии - обратите внимание, что с тех пор производительность «синхронизированного» улучшилась.)
Без более конкретной информации или метрик о вашей конкретной программе лучшее, что вы можете сделать, это просто следовать хорошему дизайну программы . Стоит отметить, что производительность и оптимизация блокировок синхронизации в JVM превзошли одну из областей (если не области), которой уделялось больше всего внимания и внимания в течение последних нескольких лет. И поэтому в последних версиях JVM все не так плохо.
В общем, я бы сказал, синхронизировать минимально, не сходя с ума . Под «минимально» я подразумеваю, чтобы вы удерживали блокировку как можно меньше времени, и чтобы только те части, которые должны использовать эту конкретную блокировку, использовали эту конкретную блокировку. Но только если изменение легко сделать и легко доказать, что ваша программа все еще верна. Например, вместо этого:
synchronized (a) {
doSomethingWith(a);
longMethodNothingToDoWithA();
doSomethingWith(a);
}
рассмотрите возможность сделать это тогда и только тогда, когда ваша программа будет по-прежнему правильной:
synchronized (a) {
doSomethingWith(a);
}
longMethodNothingToDoWithA();
synchronized (a) {
doSomethingWith(a);
}
Но помните, что странное простое обновление поля с блокировкой, удерживаемой без необходимости, вероятно, не будет иметь большого значения и может фактически улучшить производительность. Иногда может быть полезно удерживать замок немного дольше и делать меньше «уборки» замка. Но JVM может принять некоторые из этих решений , так что вам не нужно быть слишком параноиком - просто делайте разумные вещи, и у вас все будет хорошо.
В общем, попробуйте установить отдельную блокировку для каждого набора методов / обращений, которые вместе образуют «независимый процесс». Кроме этого, наличие отдельного объекта блокировки может быть хорошим способом инкапсуляции блокировки внутри класса, которым он используется (т.е. предотвращение его использования внешними вызывающими лицами способом, который вы не предсказывали), но, вероятно, нет никакой разницы в производительности от использования одного объекта к другому в качестве блокировки (например, использование самого экземпляра против частного объекта, объявленного просто как блокировка в этом классе, как вы предлагаете), при условии, что два объекта в противном случае будут использоваться в точно так же.