2017-02-15 13 views
0

Следует ли синхронизировать getConnection() внутри Enum?Безопасность потоков констант перечисления, используемых для подключения к различным базам данных

Какая из них защищена потоком?

Первое:

public enum DBConnection { 

POSTGRESQL("jdbc:postgresql://localhost:5432/mydb", "vagrant", "vagrant"), 
MYSQL("jdbc:mysql://localhost:3306/mydb", "vagrant", "vagrant"); 

DBConnection(String host, String user, String password) { 

    this.host = host; 
    this.user = user; 
    this.password = password; 
} 

private final String host; 
private final String user; 
private final String password; 

private Connection connection; 

public Connection getConnection() throws SQLException { 

    if (connection == null || connection.isClosed()) { 
     connection = DriverManager.getConnection(host, user, password); 
    } 

    return connection; 
}} 

или второй, синхронизированный вызов и изменчивой переменной:

private volatile Connection connection; 

public synchronized Connection getConnection() throws SQLException { 

    if (connection == null || connection.isClosed()) { 
     connection = DriverManager.getConnection(host, user, password); 
    } 

    return connection; 
} 

Вызов соединения, например:

 try (Connection connection = DBConnection.POSTGRESQL.getConnection()) { 
     // Prepared statement etc 
     } 
    } catch (SQLException ignored) {} 
+0

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

+0

@ Аксель, да, я знаю, но этот пример из курса Плуральсита. Автор рассматривает соединение, как указано выше. –

+0

@JanuszAgh Так как это ваш первый вопрос на сайте, прочитайте [Что делать, если кто-то отвечает на мой вопрос] (https://stackoverflow.com/help/someone-answers). Считается хорошим этикетом, чтобы поддержать ответы, которые были полезны. Вы также можете принять ответы, если они ответили на ваш вопрос или оставить комментарий к ответу, если вам нужны дополнительные разъяснения. См. Мой ответ и дайте мне знать, если вам нужна дополнительная помощь. Если нет, пожалуйста, примите ответ, нажав на галочку рядом с ним. – CKing

ответ

2

Какой потокобезопасен?

Первый вариант не поточно-, потому что у вас есть чек-то одноактный ситуации, которая может привести к состоянию гонки. Второй вариант: thread safe, но использование volatile является избыточным, если вы синхронизируете весь метод getConnection.

Тем не менее, вы лучше использовать conneciton бассейн вместо Singleton DB соединение.

+0

Для кого-то, кто задается вопросом, почему код является потокобезопасным или нет потокобезопасным, ключевым моментом для понимания является то, что каждая константа 'enum' является экземпляром' enum'. Вызов метода, который изменяет состояние константы (enum) из экземпляра «enum» из нескольких потоков, требует большинства гарантий безопасности потоков, таких как те, которые требуются для объектов типа «class». – CKing