статический метод и безопасность потока - PullRequest
4 голосов
/ 01 июня 2010

Безопасен ли следующий код?

    public static Entity getInstance(){
//the constructor below is a default one.
     return new Entity();
    }

Ответы [ 5 ]

5 голосов
/ 01 июня 2010

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

Было бы очень необычно для конструктора , а не быть потокобезопасным, но возможно ... даже если он вызывает автоматически сгенерированный конструктор по умолчанию для Entity, базовый конструктор может не быть потокобезопасным. Я не говорю, что это вероятно, просто возможно:)

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

Только статические инициализаторы (выражения инициализации для статических переменных и static { ... } блоков непосредственно внутри класса) имеют специальную обработку - виртуальная машина гарантирует, что они выполняются один раз и только один раз, блокируя другие потоки, которые ожидают, чтобы тип был инициализируется.

4 голосов
/ 01 июня 2010

Это зависит от деталей конструктора Entity. Если конструктор Entity изменяет общие данные, то это не так.

2 голосов
/ 01 июня 2010

Это, вероятно, потокобезопасно, но какой в ​​этом смысл?Если вы просто используете фабричный метод для перенаправления в конструктор по умолчанию, то почему бы не использовать конструктор в первую очередь?Итак, вопрос: чего вы пытаетесь достичь?Название getInstance() предполагает синглтон (по крайней мере, это обычная практика), но у вас явно нет синглтона.Если вы хотите одиночный, используйте класс статического внутреннего держателя, например:

    public class Singleton {

        private Singleton() {
        }

        public static Singleton getInstance() {
            return InstanceHolder.INSTANCE;
        }

        private static final class InstanceHolder {

            public static final Singleton INSTANCE = new Singleton();

        }
    }

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

1 голос
/ 01 июня 2010

Безопасность потоков - это доступ к общим данным между различными потоками. Код в вашем примере сам по себе не обращается к общим данным, но зависит от того, насколько он безопасен для потоков, зависит от того, получает ли конструктор доступ к данным, которые могут быть разделены между различными потоками.

Есть много тонких и сложных вопросов, связанных с параллельным программированием. Если вы хотите узнать о безопасности потоков и параллельном программировании в Java, я настоятельно рекомендую Брайану Гетцу Параллелизм Java на практике *1004*.

0 голосов
/ 01 июня 2010

Несколько потоков могут вызывать этот метод, и каждый из них получит уникальный экземпляр «Entity». Так что этот метод сам по себе является потокобезопасным. Но если в конструкторе или в одном из суперконструкторов есть код, который не является потокобезопасным, у вас все равно может возникнуть проблема безопасности.

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