Как синхронизированные статические методы работают на Java?

Если у меня есть class util со статическими методами, которые будут вызывать функции Hibernate для выполнения базового доступа к данным. Мне интересно, является ли synchronized метода правильным выбором для обеспечения безопасности streamов.

Я хочу, чтобы это предотвращало доступ информации к тому же экземпляру БД. Тем не менее, теперь я уверен, что следующий код предотвращает getObjectById для всех classов, когда он вызывается конкретным classом.

 public class Utils { public static synchronized Object getObjectById (Class objclass, Long id) { // call hibernate class Session session = new Configuration().configure().buildSessionFactory().openSession(); Object obj = session.load(objclass, id); session.close(); return obj; } // other static methods } 

    Используя синхронизацию при блокировке статического метода, вы синхронизируете методы и атрибуты classа (в отличие от методов и атрибутов экземпляра)

    Поэтому ваше предположение верно.

    Мне интересно, является ли синхронизация метода правильным выбором для обеспечения безопасности streamов.

    На самом деле, нет. Вы должны позволить этой работе выполнять свою RDBMS. Они хороши в этом.

    Единственное, что вы получите, синхронизируя доступ к базе данных, – сделать ваше приложение ужасно медленным. Более того, в коде, который вы опубликовали, вы каждый раз строите фабрику сеансов, таким образом ваше приложение будет тратить больше времени на доступ к БД, чем выполнение фактической работы.

    Представьте себе следующий сценарий:

    Клиент A и B пытается вставить различную информацию в запись X таблицы T.

    С вашим подходом единственное, что вы получаете, это удостовериться, что один вызван за другим, когда это все равно произойдет в БД, потому что РСУБД не позволит им вставлять половину информации из А и половины из В одновременно , Результат будет таким же, но только в 5 раз (или более) медленнее.

    Вероятно, лучше было бы взглянуть на главу «Транзакции и параллелизм» в документации Hibernate. В большинстве случаев проблемы, которые вы пытаетесь решить, были решены уже и намного лучше.

    Чтобы более подробно рассмотреть вопрос …

    Имейте в виду, что использование синхронных методов на самом деле является просто сокращенным (предположим, что class – SomeClass):

     synchronized static void foo() { ... } 

    такой же как

     static void foo() { synchronized(SomeClass.class) { ... } } 

    а также

     synchronized void foo() { ... } 

    такой же как

     void foo() { synchronized(this) { ... } } 

    Вы можете использовать любой объект в качестве блокировки. Если вы хотите заблокировать подмножества статических методов, вы можете

     class SomeClass { private static final Object LOCK_1 = new Object() {}; private static final Object LOCK_2 = new Object() {}; static void foo() { synchronized(LOCK_1) {...} } static void fee() { synchronized(LOCK_1) {...} } static void fie() { synchronized(LOCK_2) {...} } static void fo() { synchronized(LOCK_2) {...} } } 

    (для нестатических методов вы хотели бы, чтобы блокировки были нестатическими полями)

    Статические методы используют class как объект для блокировки, который является Utils.class для вашего примера. Так что да, все в порядке.

    static synchronized средство удерживает блокировку объекта classа Class где в качестве synchronized означает блокировку блокировки самого объекта classа. Это означает, что если вы получаете доступ к нестационарному синхронизированному методу в streamе (выполнения), вы все равно можете получить доступ к статическому синхронизированному методу с использованием другого streamа.

    Таким образом, доступ к двум одинаковым методам (либо двум статическим, либо двум нестационарным методам) в любой момент времени более чем streamом невозможен.

    Почему вы хотите обеспечить, чтобы только один stream мог получить доступ к БД в любой момент времени?

    Это задача драйвера базы данных для реализации любой необходимой блокировки, предполагая, что Connection используется только одним streamом за раз!

    Скорее всего, ваша firebase database идеально подходит для обработки множественного параллельного доступа

    Если это что-то связано с данными в вашей базе данных, почему бы не использовать блокировку изоляции базы данных для достижения?

    Чтобы ответить на ваш вопрос, да, это так: ваш synchronized метод не может выполняться более чем одним streamом за раз.

    Давайте будем гением компьютера.