Лучше иметь синхронизированный блок внутри блока try или блок try внутри синхронизированного блока?
Например, это лучше?
try {
synchronized (bean) {
// Write something
}
} catch (InterruptedException e) {
// Write something
}
Или это лучше:
synchronized (bean) {
try {
// Write something
}
catch (InterruptedException e) {
// Write something
}
}
Мне было интересно, какая из них - лучшая практика. Очевидно, что я должен синхронизировать весь код внутри блока try. Я не говорю о том, что мне нужно синхронизировать только часть кода внутри try (в этом случае я думаю, что было бы лучше иметь блок синхронизации внутри попытки). Мои сомнения касаются случая, когда я должен синхронизировать весь блок try.
Ответы
Ответ 1
Лучше иметь синхронизированный блок внутри блока try или блок try внутри синхронизированного блока?
Если вам явно не понадобится catch
, чтобы быть в блоке synchronized
, я сделал бы код synchronized
кода как можно меньшим и включил бы его внутри try/catch. Таким образом, первая картина будет лучше. Затем, если вам нужно выполнить операции в разделе catch
(например, журнал исключений или перерыв в потоке, см. Ниже), они не будут блокировать другие потоки.
Тем не менее, если блок synchronized
содержит несколько строк (обычно это не очень хорошая идея), я бы подумал о том, чтобы переместить блок try/catch ближе к методу, который генерирует исключение (умножить wait
или notify
). С большим количеством строк вы рискуете неправильно обрабатывать исключения с помощью больших блоков try/catch. Здесь немного зависит от системы отсчета.
В стороне, убедитесь, что вы, по крайней мере, прерывали прерывания. Никогда не игнорируйте их. Вероятно, вы также должны были прервать поток:
try {
...
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
// handle the interrupt here by logging or returning or ...
}
Ответ 2
Нет лучшей практики. Это зависит только от того, нужна ли вам часть обработки исключений внутри синхронизированного блока или нет. Вы можете захотеть того или другого, и должны выбрать тот, который делает синхронизированный блок самым коротким, при этом делая код правильным и потокобезопасным.
Ответ 3
Вы, кажется, думаете, что это всего лишь эстетический вопрос. Это не так. Это функциональный вопрос, и ответ продиктован требованием в каждом отдельном случае. Каждый синхронизированный блок должен быть настолько большим, насколько это необходимо, чтобы содержать все, что нужно синхронизировать, и не больше.
Ответ 4
Имеет ли значение, если ваш блок catch синхронизирован? Поскольку у вас есть "написать что-то", я предполагаю, что вы собираетесь делать некоторые записи, которые не должны синхронизироваться с хорошей структурой ведения журнала, что означает, что ответ, вероятно, нет.
В целом ваша цель должна заключаться в том, чтобы использовать как можно меньше синхронизации. Чем меньше ваш блок синхронизации, тем меньше вероятность того, что вы столкнетесь с проблемами.
Ответ 5
В этом случае InterruptedException
может произойти только внутри блока synchronized
, где вы можете либо вызвать wait
, либо sleep
или notify
.
В целом лучше всего поставить блок try/catch
как можно ближе к коду, который может генерировать исключение, так что легко определить код для исправления.
Ответ 6
Он не имеет ничего общего с synchronized{try{}}
или try{synchronized{}}
, но все зависит от synchronized{catch{}}
или synchronized{} catch{}
. Это действительно зависит от того, что вы делаете в блоке catch.
Однако, полагая, для InterruptedException
, вы обычно должны делать catch{}
вне synchronized{}
.