当前位置: 首页 > 面试题库 >

HikariCP包装器(线程安全)

周昊乾
2023-03-14
问题内容

我正在学习使用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本身是线程安全的。据我了解,您正在尝试做的是阻止调用者通过方法初始化getConnection()之前的。大概您还想防止多次调用数据源。HikariDataSource``init()``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!!!!!."); 
  }
}


 类似资料:
  • 问题内容: 当前提供以下实用程序方法来为各种收集接口创建包装器: 类似地,它也有6个重载。 明显的遗漏是这里的实用方法。的确如此,但and 和and 确实有专用于and的实用程序方法。大概是一个有用的抽象,否则它本来就不会存在的,但是还没有实用的方法。 所以问题是: 为什么不提供实用方法的特定原因? 您将如何编写自己的包装器? 浏览OpenJDK版本的源代码似乎表明这只是一个“机械”过程 通常,您

  • 本文向大家介绍Postman安装与使用详细教程 附postman离线安装包,包括了Postman安装与使用详细教程 附postman离线安装包的使用技巧和注意事项,需要的朋友参考一下 Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大

  • WMP10 05年2月15日发布之后就没有更新了,中间有更新补丁。所以我们可以把补丁及WMP10做个安装包就方便一点了! 首先下载WMP10和补丁: 2005/2/15 Windows Media Player 10 /Q:A /c:"setup_wm.exe /DisallowSystemRestore /Q /R:N" 使用 Windows Media Player 10 尽享音乐和视频。 2

  • 问题内容: 我从一个非常简单的多线程示例开始。我试图做一个线程安全的计数器。我想创建两个线程,使计数器间歇地增加到1000。以下代码: 据我所知,while循环现在意味着只有第一个线程才能访问计数器,直到达到1000。输出: 我该如何解决?如何获得共享计数器的线程? 问题答案: 两个线程都可以访问您的变量。 您看到的现象称为线程饥饿。输入代码的受保护部分后(很抱歉,我之前错过了它),其他线程将需要

  • 问题内容: 我需要使ArrayLists线程的ArrayList安全。我也不能让客户对集合进行更改。不可修改的包装器会使其线程安全吗,或者我需要在集合上使用两个包装器? 问题答案: 这取决于。包装器只会阻止对其包装的集合进行更改,而不是对集合中的对象进行更改。如果您有一个ArrayLists的ArrayList,则全局列表及其每个元素列表都需要单独包装,并且您可能还需要为这些列表的内容做些事情。最

  • 给stackoverflow社区的人们。我正在寻找一些帮助,以解决HikariCP连接池面临的问题。 高级:我正在尝试使用线程池创建多个线程,我的计划是为每个工作线程提供独立于HikariCP的连接,但HikariCP所做的是在多个线程之间共享一个公共连接。我正在使用 以检索DB连接。现在,当我关闭一个连接时,我在其他线程中看到问题,说连接关闭了,线程正在处理的批次记录被丢弃。 以下是我的日志文件