синхронизированные статические методы - PullRequest
4 голосов
/ 28 февраля 2012

Если у меня есть класс с несколькими синхронизированными методами, некоторые из них являются статическими, а некоторые нет:

public class A {
    public static void synchronized f1() {}
    public void synchronized f2() {}
}  

, что происходит, когда один поток вызывает f1 (), а второй вызывает f2 (), это значит, как они синхронизируются друг с другом.и что произойдет, если один протектор вызывает f1 (), а f1 () вызывает f2 () ???

Ответы [ 3 ]

9 голосов
/ 28 февраля 2012

Они не синхронизированы друг с другом вообще.Статический метод синхронизирован на A.class, второй - на this.Так что (почти), как если бы вы написали:

public class A {
    public static void f1() {
        synchronized(A.class) {
            ...
        }
    }

    public void f2() {
        synchronized(this) {
            ...
        }
    }
}

, и что произойдет, если один протектор вызовет f1 (), а f1 () вызовет f2 ()

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

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

1 голос
/ 28 февраля 2012

Синхронизированный статический метод синхронизируется с соответствующим объектом Class класса, поэтому он отличается от блокировки, используемой методами экземпляра.Очевидно, что статический метод не имеет доступа к this.Таким образом, ваши методы f1 () и f2 () не синхронизируются друг с другом, только с другими статическими или другими методами экземпляра класса.

1 голос
/ 28 февраля 2012

Синхронизированный статический метод синхронизируется с объектом Class , а не с экземпляром.

f1() и f2() могут вызываться двумя отдельными потоками и будут выполняться одновременно.

См .: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#260369

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