Синхронизация касается статического метода в Java - PullRequest
3 голосов
/ 22 июня 2011

Предположим, у меня есть класс Utility,

public class Utility {

    private Utility() {} //Don't worry, just doing this as guarantee.

    public static int stringToInt(String s) {
        return Integer.parseInt(s);
    }
};

Теперь предположим, что в многопоточном приложении поток вызывает, Utility.stringToInt() метод и , в то время как операция входит в вызов метода, другой поток вызывает тот же метод, передавая другой s. Что происходит в этом случае? Блокирует ли Java статический метод?

Ответы [ 5 ]

10 голосов
/ 22 июня 2011

Здесь нет проблем. Каждый поток будет использовать свой собственный стек, поэтому между различными s нет точки столкновения. И Integer.parseInt() является потокобезопасным, поскольку использует только локальные переменные.

3 голосов
/ 22 июня 2011

Java не блокирует статический метод, если только вы не добавите ключевое слово synchronized.

Обратите внимание, что когда вы блокируете статический метод, вы получаете Mutex объекта Class, в котором реализован метод, поэтомусинхронизация в статическом методе не позволит другим потокам войти в любой из других «синхронизированных» статических методов.

Теперь, в вашем примере, вам не нужно синхронизировать в этом конкретном случае.Это потому, что параметры передаются копией;Таким образом, несколько вызовов статического метода приведут к нескольким копиям параметров, каждый в своем собственном кадре стека.Аналогичным образом, при одновременных вызовах Integer.parseInt(s) каждый будет создавать свой собственный кадр стека с копиями значения s, передаваемого в отдельные кадры стека.

Теперь, если Integer.parseInt (...) был реализован очень плохоспособ (он использовал статические не финальные члены во время выполнения parseInt; тогда была бы серьезная причина для беспокойства. К счастью, разработчики библиотек Java являются лучшими программистами, чем это.

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

В приведенном вами примере нет общих данных между потоками И нет данных, которые могут быть изменены. (Вам понадобится и то и другое, чтобы возникла проблема с потоками)


Вы можете написать

public enum Utility {
    ; // no instances

    public synchronized static int stringToInt(String s) {
        // does something which needs to be synchronised.
    }
}

это фактически то же самое, что и

public enum Utility {
    ; // no instances

    public static int stringToInt(String s) {
        synchronized(Utility.class) {
            // does something which needs to be synchronised.
        }
    }
}

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

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

Синхронизация здесь не требуется, поскольку переменная s является локальной.

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

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

Не должно быть, если не указано явно.Кроме того, в этом случае не будет никаких проблем с безопасностью потоков, поскольку "s" является неизменным и также локальным для метода.

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