许多线程使用C3P0和Hibernate / Spring创建

时间:2012-12-12 12:43:15

标签: java mysql multithreading hibernate c3p0

我在Java环境中使用Tomcat在Java Web应用程序中合并Hibernate和Spring。由于Mysql 8小时超时问题,我们希望使用C3P0来管理与我们的Mysql数据库的连接池。 但是当我们使用它时,我们创建了许多线程。我想通了,因为我在每次请求时都打印了所有这些打印机,其内存状态向我显示了不断增加的内存和那种线程:

  
      
  • name:C3P0PooledConnectionPoolManager [identityToken-> 1hged7o8r13kpj7n1h3ycia | 39c446] -HelperThread-#0守护进程:真正的组! main groupParent:system alive:true interrupted:false
  •   
  • name:C3P0PooledConnectionPoolManager [identityToken-> 1hged7o8r13kpj7n1h3ycia | 17ec0e8] -AdminTaskTimer守护程序:真正的组! main groupParent:system alive:true interrupted:false
  •   

在足够的时间之后,它可以产生超过500个这样的线程。

这是我的Hibernate.cfg.xml:

    <property name="connection.provider_class">
            org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="hibernate.c3p0.acquire_increment">1</property> 
    <property name="hibernate.c3p0.idle_test_period">5</property>
    <property name="hibernate.c3p0.max_size">100</property> 
    <property name="hibernate.c3p0.max_statements">100</property> 
    <property name="hibernate.c3p0.min_size">10</property> 
    <property name="hibernate.c3p0.timeout">5</property>

    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myBase</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.default_schema">myProject</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
    <property name="show_sql">false</property>

    <property name="cache.provider_class">
      org.hibernate.cache.NoCacheProvider
    </property>         

我还尝试添加一个C3P0 propeties文件,但除了减少辅助线程号外,它不会删除未使用的线程:

    c3p0.maxStatements=5    

c3p0.maxIdleTime=10

c3p0.numHelperThreads=1

c3p0.testConnectionOnCheckout=true
c3p0.preferredTestQuery=SELECT 1

c3p0.initialPoolSize=1
c3p0.minPoolSize=1
c3p0.maxPoolSize=10

c3p0.acquireIncrement=1
c3p0.idleConnectionTestPeriod=1

有没有人知道为什么会这样,以及如何解决这个问题?

非常感谢。

3 个答案:

答案 0 :(得分:1)

我希望它能创建一些与c3p0.minPoolSize成比例的线程 和c3p0.maxPoolSize,你的最大值是10。

http://www.mchange.com/projects/c3p0/#other_ds_configuration numHelperThreads 和maxAdministrativeTaskTime有助于配置DataSource线程池的行为。默认情况下,每个DataSource只有三个关联的帮助程序线程。如果性能似乎在重负载下拖累,或者如果您通过JMX观察或直接检查PooledDataSource,那么“待处理任务”的数量通常大于零,请尝试增加numHelperThreads。对于遇到无限期挂起的任务和“APPARENT DEADLOCK”消息的用户,maxAdministrativeTaskTime可能很有用。附录A了解更多。)“

numHelperThreads定义每个DataSource使用多少个线程,因此确实有10个线程numHelperThreads=1

确保C3P0只消耗一个线程的唯一方法是设置c3p0.minPoolSizec3p0.maxPoolSize到1但这会破坏连接池的目的。

答案 1 :(得分:1)

如果您看到c3p0助手和计时器线程的乘法,那么当您希望只有一个时,您就会以某种方式创建大量的c3p0数据源。有时会发生这种情况,如果您正在热重新加载应用程序但忘记在回收时关闭()旧的c3p0数据源。

有效地看起来你正在“泄漏”DataSources。你需要找出原因/发生的原因。对于一些线索,请在INFO级别查看日志中的c3p0 DataSource初始化消息。例如,搜索字符串“Initializing c3p0 pool”。

祝你好运!

答案 2 :(得分:1)

好的,我找到了一系列属性来解决我的问题,请记住我一次不需要很多连接:

  • c3p0.maxStatements = 5
  • c3p0.maxIdleTime = 10
  • c3p0.numHelperThreads = 3
  • c3p0.testConnectionOnCheckout = true
  • c3p0.preferredTestQuery = SELECT 1
  • c3p0.initialPoolSize = 1
  • c3p0.minPoolSize = 1
  • c3p0.maxPoolSize = 1 c3p0.acquireIncrement = 1
  • c3p0.idleConnectionTestPeriod = 1
  • c3p0.maxAdministrativeTaskTime = 1

感谢所有人