Почему я не могу синхронизировать экземпляр блока в Java? - PullRequest
0 голосов
/ 19 июня 2011

Когда я попытался выполнить следующие действия:

public class Test {

    synchronized(this){   // compiler complains here
        System.out.println("instance block");
    }

    public static void main(String [] args){

    }

}

Разве синхронизация блока экземпляра не похожа на синхронизацию блока операторов?

Спасибо, Бхарат

Ответы [ 5 ]

2 голосов
/ 19 июня 2011

Хотя вы можете synchronized(this) в блоке инициализатора экземпляра или в конструкторе, это всегда бессмысленно, поскольку объект не будет использоваться совместно на этом этапе. то есть он доступен только для одного потока.

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

1 голос
/ 19 июня 2011

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

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

1 голос
/ 19 июня 2011

Разве синхронизация блока экземпляров не похожа на синхронизацию блока операторов?

AFAIK, нет, потому что это не просто «блок операторов», а инициализатор экземпляра. Если вы хотите, чтобы выполнение блока было синхронизировано, вы всегда можете синхронизироваться по ссылке this внутри инициализатора. Кроме того, я не думаю, что вы можете синхронизировать блоки верхнего уровня (блоки методов имеют специальную синтаксическую поддержку для этого, как вы уже знаете).

public class Test {

    // can't synchronize on a top-level block
    synchronized(this) {
    }

    {
        // OK
        synchronized(this) {
        }
    }

    // Methods have special syntactic support
    public synchronized void doIt() {
    }

    public void doIt() {
        // same as above
        synchronized(this) {
        }
    }
}
1 голос
/ 19 июня 2011

Почему бы вам не выполнить синхронизацию внутри:

public class Test {

    {
        synchronized(this) {
            System.out.println("instance block");
        }
    }

    public static void main(String [] args){

    }

}
0 голосов
/ 19 июня 2011

Поскольку этого нет в блоке статического инициализатора.

Этот блок выполняется при загрузке определения класса, а не при создании экземпляра.

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

Короче, сохраняйте блок и удаляйте синхронизированный (это)

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