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

Лучше иметь синхронизированный блок внутри блока 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.

4b9b3361

Ответ 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{}.