Java-класс Properties
является поточно-класса в соответствии с его документацией:Должен ли я получить блокировку свойств перед циклом setProperety?
Этот класс является поточно-: несколько потоков могут совместно использовать один Свойства объекта без необходимости внешней синхронизации.
Из-за этой причине, у меня есть привычка поддерживать свои свойства в HashMap
реализации Map
, которая не является поточно-, но гораздо более легкий. Более конкретно, для обеспечения безопасности потоков требуются дополнительные блокирующие механизмы, которые будут влиять на производительность. Я могу легко избежать этого, просто выделив инициализацию моего свойства в статическом инициализаторе класса, что гарантирует его завершение, прежде чем я буду использовать любые вызовы get в методах экземпляра того же класса.
Это до сих пор было просто повествованием, которое привело меня к реальному вопросу. В конце концов мне нужно вернуться к API, который может принимать только «Свойства» в качестве параметра, например, DriverManager.getConnection(String,Properties)
. Мне нужно преобразовать Map
в Properties
.
Так первая попытка будет выглядеть как-то вроде этого:
Properties properties = new Properties();
this.propertyMap.forEach((k,v)->{properties.setProperty(k, v);});
connection = DriverManager.getConnection(url, properties);
Очевидная проблема, или, может быть, не столь очевидно, как я избегал использования актуальной для цикла, то, что я использую повторный вызов Properties.setProperty
. Если Properties
действительно потокобезопасен, то это должно означать, что каждый вызов setProperty
синхронизирован и имеет отдельные механизмы блокировки/разблокировки.
Не было бы лучше в таком случае, чтобы я вручную заблокировал весь экземпляр Properties
, как в коде ниже?
Connection connection;
Properties properties = new Properties();
synchronized (properties) {
// Properties is implemented as thread-safe. As it adds
// additional thread locking, it's use is localized to just
// here to avoid consequential performance issues. We will
// do a last minute conversion from Map to Properties right here.
this.propertyMap.forEach((k,v)->{properties.setProperty(k, v);});
connection = DriverManager.getConnection(url, properties);
}
Один из вопросов, я, возможно, ожидал, что оба ручной блокировки по свойствам, так и индивидуальные вызовы к setProperties
могла бы привести к тупиковой ситуации, но, кажется, прекрасно работать.
Не существует синхронизации точек в локальном экземпляре 'Свойства'. Я бы подумал о блокировке на 'ProperyMap', но тогда каждый раз, когда вы хотели обновить карту, вам также нужно будет блокировать ее, чтобы предотвратить возможную мутацию между потоками. – MadProgrammer
блокировки являются реентерабельными. также неустранимые синхронизации бывают быстрыми. так что это, возможно, не стоит беспокоиться. –
@MadProgrammer Я избегаю одновременной мутации экземпляра «Карта», следуя соглашению, а не блокировке. Это то, что я пытался объяснить в разделе, посвященном моему фактическому вопросу. Но почему нет смысла синхронизировать локальный экземпляр «Свойства»? – YoYo