簡體   English   中英

HikariCP包裝器(線程安全)

[英]HikariCP Wrapper (thread safety)

我正在學習使用HikariCP(我是Java新手),我發現了一個包裝器,但我認為這不是線程安全性,那么單例的實例是線程安全性,而不是方法getConnection()。 該類是這樣的:

public class HikariCPWrapper{
    private static final HikariCPWrapper INSTANCE;
    private HikariDataSource ds;
    static  
    {  
    INSTANCE = new HikariCPWrapper();    
    }  

    private HikariCPWrapper(){
        HikariConfig config = new HikariConfig(); 
        //config.set... 
        //... 
        ds = new HikariDataSource(config);  

    }

    public static HikariCPWrapper getInstance ()  
    {  
        return INSTANCE;  
    }  

    public Connection getConnection()  throws SQLException  
    {  
        return ds.getConnection();  
    }  
}

好吧,我需要將參數發送到HikariConfig或HikariDataSource,所以我以這種方式重新編寫了它:

public interface IConnectionProvider {
    void init(String jdbcUrl, String user, String password);
    Connection getConnection() throws SQLException;
}

    public class ConnectionProviderHikariCP implements IConnectionProvider{

    private static final ConnectionProviderHikariCP INSTANCE;
    private final HikariDataSource hikariDataSource;
    private Boolean initialized;
    //class initializer:
    static
    {
        INSTANCE = new ConnectionProviderHikariCP();
    }

    private ConnectionProviderHikariCP() {
        hikariDataSource = new HikariDataSource();
        initialized = false;
    }

    public static ConnectionProviderHikariCP getInstance() {
        return INSTANCE;
    }

    @Override
    public synchronized void init(String jdbcUrl, String user, String password) {
        hikariDataSource.setJdbcUrl(jdbcUrl);        
        hikariDataSource.setUsername(user);
        hikariDataSource.setPassword(password);
        initialized = true;
    }

    @Override
    public synchronized Connection getConnection() throws SQLException {
        if(!initialized)
           throw new UnsupportedOperationException("Debe inicializar mediante el método Init() primero!!!!!."); 

        return hikariDataSource.getConnection();
    }

}

我用這種方式:

IConnectionProvider connectionProvider = ConnectionProviderHikariCP.getInstance();
connectionProvider.init(url, user, passwd);

BaseDAOFactory fatory = new MySqlDAOFactory(connectionProvider);
IExerciseBO exerciseBO = new ExerciseBO(fatory); 

但是我沒有Java經驗,所以我需要您的建議。 一流(原始)線程安全嗎? 我的實現線程安全嗎?

HikariCP本身是線程安全的。 據我了解,您正在嘗試做的是防止通過init()方法初始化HikariDataSource之前的調用者getConnection() 大概您還想防止多次調用init()數據源。

就池吞吐量而言,用同步方法包裝getConnection()通常是一個壞主意。 根據上面的代碼,我建議使用以下模式:

public class ConnectionProviderHikariCP implements IConnectionProvider {

  private static final ConnectionProviderHikariCP INSTANCE;
  private final HikariDataSource hikariDataSource;
  private AtomicBoolean initialized;
  //class initializer:
  static
  {
     INSTANCE = new ConnectionProviderHikariCP();
  }

  private ConnectionProviderHikariCP() {
     hikariDataSource = new HikariDataSource();
     initialized = new AtomicInteger();
  }

  public static ConnectionProviderHikariCP getInstance() {
     return INSTANCE;
  }

  @Override
  public void init(String jdbcUrl, String user, String password) {
     if (initialized.compareAndSet(false, true)) {
        hikariDataSource.setJdbcUrl(jdbcUrl);        
        hikariDataSource.setUsername(user);
        hikariDataSource.setPassword(password);
     }
     else {
        throw new IllegalStateException("Connection provider already initialized.");
     }
  }

  @Override
  public Connection getConnection() throws SQLException {
     if (initialized.get()) {
        return hikariDataSource.getConnection();
     }

     throw new UnsupportedOperationException("Debe inicializar mediante el método Init() primero!!!!!."); 
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM