精华内容
下载资源
问答
  • 1. 概念:其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。2. ...

    1. 概念:其实就是一个容器(集合),存放数据库连接的容器。

    当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

    2. 好处:

    1. 节约资源

    2. 用户访问高效

    3. 实现:

    1. 标准接口:DataSource javax.sql包下的

    1. 方法:

    * 获取连接:getConnection()

    * 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接

    2. 一般我们不去实现它,有数据库厂商来实现

    1. C3P0:数据库连接池技术

    2. Druid:数据库连接池实现技术,由阿里巴巴提供的

    4. C3P0:数据库连接池技术

    * 步骤:

    1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,

    * 不要忘记导入数据库驱动jar包

    2. 定义配置文件:

    * 名称: c3p0.properties 或者 c3p0-config.xml

    * 路径:直接将文件放在src目录下即可。

    3. 创建核心对象 数据库连接池对象 ComboPooledDataSource

    4. 获取连接: getConnection

    * 代码:

    //1.创建数据库连接池对象

    DataSource ds = new ComboPooledDataSource();

    //2. 获取连接对象

    Connection conn = ds.getConnection();

    5. Druid:数据库连接池实现技术,由阿里巴巴提供的

    1. 步骤:

    1. 导入jar包 druid-1.0.9.jar

    2. 定义配置文件:

    * 是properties形式的

    * 可以叫任意名称,可以放在任意目录下

    3. 加载配置文件。Properties

    4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory

    5. 获取连接:getConnection

    * 代码:

    //3.加载配置文件

    Properties pro = new Properties();

    InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");

    pro.load(is);

    //4.获取连接池对象

    DataSource ds = DruidDataSourceFactory.createDataSource(pro);

    //5.获取连接

    Connection conn = ds.getConnection();

    2. 定义工具类

    1. 定义一个类 JDBCUtils

    2. 提供静态代码块加载配置文件,初始化连接池对象

    3. 提供方法

    1. 获取连接方法:通过数据库连接池获取连接

    2. 释放资源

    3. 获取连接池的方法

    * 代码:

    import java.io.InputStream;

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.PreparedStatement;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.util.Properties;

    import javax.sql.DataSource;

    import com.alibaba.druid.pool.DruidDataSourceFactory;

    /**

    * 获取我们的数据库连接

    * 关闭我们的连接对象

    * @author ls

    */

    public class DBUtilsDataSource {

    static DataSource dataSource; //连接池接口

    static {

    try {

    //获取一个properties的文件

    InputStream is = DBUtilsDataSource.class.getClassLoader().getResourceAsStream("druid.properties");

    Properties properties = new Properties();

    properties.load(is);

    //需要一个接口的实现者, 来给这个接口 赋值;

    //思考一下,为什么我们还需要一个properties文件???

    //我们连接数据库的驱动,连接串,用户名,密码,是我们给连接池,还是连接池自己就有了

    //连接池根据这个配置文件来连接我们的数据库;

    dataSource=DruidDataSourceFactory.createDataSource(properties);

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    /**

    * 使用连接池的这个技术,来获取连接;

    * 通过连接池来得到一个连接

    * @return

    */

    public static Connection getConnection() {

    try {

    //这里是使用连接池的方式来获取连接

    return dataSource.getConnection(); //从连接池里面获取一个连接

    } catch (SQLException e) {

    e.printStackTrace();

    }

    return null;

    }

    // 提供静态方法,关闭我们的结果集; 关闭我们的 ps对象; 关闭我们的连接对象;

    public static void close(Connection con, PreparedStatement ps, ResultSet rs) {

    closeResultSet(rs); // 关闭结果集

    closePreparedStatement(ps); // 关闭操作数据库的对象

    closeConnection(con);// 关闭连接

    }

    private static void closeResultSet(ResultSet rs) {

    if (rs != null) {

    try {

    rs.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    }

    private static void closePreparedStatement(PreparedStatement ps) {

    if (ps != null) {

    try {

    ps.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    }

    private static void closeConnection(Connection con) {

    if (con != null) {

    try {

    con.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    }

    }

    展开全文
  • 数据库连接池线程池比较 数据库连接池是为了复用数据库连接Connections,因为数据库连接的获取和销毁开销代价大;线程池是为了复用线程,因为线程上下文切换开销代价大;他们的核心思想都是对资源的复用。那他们...

    数据库连接池和线程池比较

    数据库连接池是为了复用数据库连接Connections,因为数据库连接的获取和销毁开销代价大;线程池是为了复用线程,因为线程上下文切换开销代价大;他们的核心思想都是对资源的复用。那他们之间有什么异同呢,我们用mybatis中的数据库连接池来和java线程池做对比。

    在这里插入图片描述

    展开全文
  • 线程池 相关配置,不仅平时经常用到,而且面试也会经常问到。如何设置线程池大小?CPU 密集型任务:这种任务消耗的主要是 CPU 资源,可以将线程数设置为 N(CPU 核心数)+1,比 CPU 核心数多出来的一个线程是为了防止...

    线程池 相关配置,不仅平时经常用到,而且面试也会经常问到。

    如何设置线程池大小?

    CPU 密集型任务:这种任务消耗的主要是 CPU 资源,可以将线程数设置为 N(CPU 核心数)+1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间。

    I/O 密集型任务:这种任务应用起来,系统会用大部分的时间来处理 I/O 交互,而线程在处理 I/O 的时间段内不会占用 CPU 来处理,这时就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务的应用中,我们可以多配置一些线程,具体的计算方法是 2N。

    综上可知:当线程数量太小,同一时间大量请求将被阻塞在线程队列中排队等待执行线程,此时 CPU 没有得到充分利用;当线程数量太大,被创建的执行线程同时在争取 CPU 资源,又会导致大量的上下文切换,从而增加线程的执行时间,影响了整体执行效率。通过测试可知,4~6 个线程数是最合适的。

    public ThreadPoolExecutor(int corePoolSize,//线程池的核心线程数量

    int maximumPoolSize,//线程池的最大线程数

    long keepAliveTime,//当线程数大于核心线程数时,多余的空闲线程存活的最长时间

    TimeUnit unit,//时间单位

    BlockingQueue workQueue,//任务队列,用来储存等待执行任务的队列

    ThreadFactory threadFactory,//线程工厂,用来创建线程,一般默认即可

    RejectedExecutionHandler handler) //拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务

    8df908af6e67834088fc6f72a214c66e.png

    911e00485e09406e21e03c75e7d873dd.png

    但是某些号称XXX架构师配置线程池参数(或者jdbc连接池数量)还是会拍脑袋,随便定个 核心线程数或者最大线程数100

    这就是没有性能意思的码农(估计都了解过怎么配置,就是没有在意)了。 虽然说配置比如 最大线程数100 , 其实对于并发量不大的项目来说,其实运行起来也不会出什么问题。但是 能改则改。

    // CPU 核心数:

    // 核数 。CPU密集计算:N+1// IO类型的就是:2Nintcores = Runtime.getRuntime().availableProcessors();

    线程池 spring boot 异步执行任务配置实例, 一般都是CPU类型的异步任务

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

    import org.springframework.scheduling.annotation.EnableAsync;

    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

    import java.util.concurrent.Executor;

    import java.util.concurrent.ThreadPoolExecutor;

    /**

    * 自定义异步线程的执行器

    * 使用 ThreadPoolTaskExecutor 线程池方式,避免开启过多的线程

    *

    * @author James

    * @date 2018/7/16 上午11:40

    */

    @Configuration

    @EnableAsync

    public class ExecutorConfig

    {

    /**

    * Set the ThreadPoolExecutor's core pool size.

    */

    private int corePoolSize = 4;

    /**

    * Set the ThreadPoolExecutor's maximum pool size.

    */

    private int maxPoolSize = Runtime.getRuntime().availableProcessors() + 3;

    /**

    * Set the capacity for the ThreadPoolExecutor's BlockingQueue.

    * 队列数不能太大,否则就会任务堆积,处理就太慢了。

    */

    private int queueCapacity = 300;

    @Bean

    public Executor myAsync()

    {

    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

    executor.setCorePoolSize(corePoolSize);

    executor.setMaxPoolSize(maxPoolSize);

    executor.setQueueCapacity(queueCapacity);

    executor.setThreadNamePrefix("MyExecutor-");

    // rejection-policy:当pool已经达到max size的时候,如何处理新任务

    // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 。 一般这种任务不能丢弃

    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

    executor.initialize();

    return executor;

    }

    }

    以上代码就是 当spring boot 中 执行 异步 代码的时候所用到的线程池配置了: 即加了 @Async 的方法

    线程池任务拒绝策略

    LinkedBlockingQueue和ArrayBlockingQueue迥异

    自定义CPU密集型线程池例子

    使用 LinkedBlockingQueue 是因为其可以有更高的吞吐量

    import com.google.common.util.concurrent.ThreadFactoryBuilder;

    import org.slf4j.Logger;

    import org.slf4j.LoggerFactory;

    import org.springframework.stereotype.Component;

    import java.util.concurrent.*;

    @Component

    public class ExecutionResultPool {

    private static final Logger logger = LoggerFactory.getLogger(ExecutionResultPool.class);

    private ExecutorService threadPool;

    public void init() {

    // 核数 。 CPU 密集计算: N+1

    // IO 类型的就是: 2N

    int cores = Runtime.getRuntime().availableProcessors();

    ThreadFactory threadFactory = new ThreadFactoryBuilder()

    .setNameFormat("timing-executor-pool-%d").build();

    threadPool = new ThreadPoolExecutor(4,

    cores+3, 30, TimeUnit.SECONDS,

    new LinkedBlockingQueue<>(1000),

    threadFactory,

    (r, executor) -> {

    try {

    // // 尝试再次加入队列。如果队列已满,那么等待,直到队列空了就放进去

    executor.getQueue().put(r);

    } catch (InterruptedException e) {

    logger.error("任务加入队列失败", e);

    Thread.currentThread().interrupt();

    }

    });

    logger.info("初始化任务执行线程池 {}", threadFactory);

    }

    public void execute(Runnable runnable) {

    threadPool.execute(runnable);

    }

    }

    数据库连接池配置

    发现一些同时将最大连接数配置到了100左右,其实也是随便拍脑袋的结果。

    展开全文
  • 一、数据库连接池 1、数据库连接池 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为...

    一、数据库连接池

    1、数据库连接池

    数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

     2、好处

    1)资源重用 2)快速响应 3)新的资源分配手段  4) 统一的连接管理,避免数据库连接泄漏

    3、数据库连接池的实现

    使用动态代理实现Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler())实现连接池。

    二、线程池

    一个线程池的组成:

    1. 线程池管理器(ThreadPoolManager):用于创建并管理线程池

    2. 工作线程(WorkThread): 线程池中线程

    3. 任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。

    4. 任务队列:用于存放没有处理的任务。提供一种缓冲机制。

     线程池的核心参数:

    corePoolSize    线程池维护线程的最少数量;核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;

    最佳线程数:最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

    maximumPoolSize  线程池维护线程的最大数量 

    keepAliveTime   线程空闲时间 ,所以如果任务很多,并且每个任务执行的时间比较短,可以适当调大这个参数来提高线程的利用率。表示线程没有任务执行时最多保持多久时间会终止。

    workQueue    任务队列,用来存放我们所定义的任务处理线程,

    keepAliveTime 参数的单位,可选的单位:天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS)和纳秒(NANOSECONDS)

     

    在ThreadPoolExecutor类中提供了四个构造方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class ThreadPoolExecutor extends AbstractExecutorService {
        .....
        public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                BlockingQueue<Runnable> workQueue);
     
        public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
     
        public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
     
        public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
        ...
    }
     
    线程池的分类:
     

    1、newCachedThreadPool

    作用:创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,并在需要时使用提供的 ThreadFactory 创建新线程。

    特征: 
    (1)线程池中数量没有固定,可达到最大值(Interger. MAX_VALUE) 
    (2)线程池中的线程可进行缓存重复利用和回收(回收默认时间为1分钟) 
    (3)当线程池中,没有可用线程,会重新创建一个线程

    创建方式: Executors.newCachedThreadPool();

    2、newFixedThreadPool

    作用:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。

    特征: 
    (1)线程池中的线程处于一定的量,可以很好的控制线程的并发量 
    (2)线程可以重复被使用,在显示关闭之前,都将一直存在 
    (3)超出一定量的线程被提交时候需在队列中等待

    创建方式: 
    (1)Executors.newFixedThreadPool(int nThreads);//nThreads为线程的数量 
    (2)Executors.newFixedThreadPool(int nThreads,ThreadFactory threadFactory);//nThreads为线程的数量,threadFactory创建线程的工厂方式

    3、newSingleThreadExecutor

    作用:创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的 newFixedThreadPool(1) 不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。

    特征: 
    (1)线程池中最多执行1个线程,之后提交的线程活动将会排在队列中以此执行

    创建方式: 
    (1)Executors.newSingleThreadExecutor() ; 
    (2)Executors.newSingleThreadExecutor(ThreadFactory threadFactory);// threadFactory创建线程的工厂方式

    4、newScheduleThreadPool

    作用: 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

    特征: 
    (1)线程池中具有指定数量的线程,即便是空线程也将保留 
    (2)可定时或者延迟执行线程活动

    创建方式: 
    (1)Executors.newScheduledThreadPool(int corePoolSize);// corePoolSize线程的个数 
    (2)newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);// corePoolSize线程的个数,threadFactory创建线程的工厂

    5、newSingleThreadScheduledExecutor

    作用: 创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。

    特征: 
    (1)线程池中最多执行1个线程,之后提交的线程活动将会排在队列中以此执行 
    (2)可定时或者延迟执行线程活动

    创建方式: 
    (1)Executors.newSingleThreadScheduledExecutor() ; 
    (2)Executors.newSingleThreadScheduledExecutor(ThreadFactory threadFactory) ;//threadFactory创建线程的工厂

     

     
     

    转载于:https://www.cnblogs.com/yebingluo/p/10246420.html

    展开全文
  • 线程池线程池的原理类似于操作系统中的缓冲区的概念。先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个...
  • Java学习之数据库连接池0x00 前言前面用到的jdbc,在每次连接数据库的时候都需要去重新建立对象。我们在这里会用到创建一个连接池,每次使用完后归还给连接池。0x01 连接池概述连接池其实就是一个容器(集合),存放...
  • 这里继续更JDBC的工具类,应该是V5版本了:V5版本引入了线程池,为了后面项目service层方便进行事务操作:创建线程池:private static ThreadLocal t=new ThreadLocal();package cn.hncu.pub;import java.lang....
  • 一、Java数据库连接池总结  数据库连接池的实现及原理   内容摘要: 对于一个复杂的数据库应用,频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。  有一个很著名的设计...
  • 数据库连接池线程池,C3P0

    千次阅读 2015-11-09 19:39:56
    1.数据库连接池 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接...
  • 在程序中使用数据库连接池线程池,可以有效地改善系统在高并发下的性能。 数据库连接池 目前应用较为广泛的数据库连接池组件有C3PO和Proxool。其中C3PO是伴随着Hibernate一起发布,与Hibernate联系紧密的数据库...
  • 当客户端请求的数据量比较大...本文我们主要就介绍一下线程池数据库连接池的原理,接下来我们一起来了解一下这一部分内容。线程池的原理:其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下...
  • 数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池( 简单说:在一个“池”里放了好多半成品的数据库联接对象),由应用程序动态地对池中的连接进行申...
  • 提升性能----数据库连接池以及线程池以及对象池 目录:数据库连接池c3po,线程池ExecutorService:Jakartacommons-pool对象池 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:...
  • 一、为什么要用Http连接池1、降低...基本上3倍的时间延迟2、支持更大的并发:如果不采用连接池,每次连接都会打开一个端口,在大并发的情况下系统的端口资源很快就会被用完,导致无法建立新的连接一、 线程池的原...
  • 一直觉得数据库连接池是一个很神秘的东西,现在来自己动手模拟一个数据库连接池。数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用...
  • 网上找了写资料: 数据库连接池: 数据库连接是一种关键的有限的昂贵的资源,这一点在... 数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池(简单说:在一个“池”里...
  • 数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库联接对象),由应用程序动态地对池中的连接进行申请、使用和...
  • 当客户端请求的数据量比较大的时候,使用...本文我们主要就介绍一下线程池数据库连接池的原理,接下来我们一起来了解一下这一部分内容。 线程池的原理: 其实线程池的原理很简单,类似于操作系统中的缓冲区的概
  • 本文内容95%译自这篇文章:... 我在研究HikariCP(一个数据库连接池)时无意间在HikariCP的Github wiki上看到了一篇文章(即前面给出的链接),这篇文章有力地消除了我一直以来的疑虑,看完之后感觉神清气爽...
  • 当客户端请求的数据量比较大...本文我们主要就介绍一下线程池数据库连接池的原理,接下来我们一起来了解一下这一部分内容。线程池的原理:其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下...
  • 简单介绍一下线程池数据库连接池的原理 2011-08-09 15:25 zhongguoren666 CSDN博客 我要评论(0) 字号:T | T 本文我们简单介绍了一下数据库连接池线程池的工作原理,希望能够对您有所帮助。 AD: 51...
  • 线程池数据库连接池的原理

    千次阅读 2016-06-08 23:06:29
    本文我们简单介绍了一下数据库连接池线程池的工作原理,希望能够对您有所帮助。   当客户端请求的数据量比较大的时候,使用线程池可以节约大量的系统资源,使得更多的CPU时间和内存可以高效地利用起来。而...
  • 应该没人仅限一个,这样可以减轻服务器的负担,并且这种方式能够让其他对象来对数据库进行事务操作时,不用辨别是哪种对象,因为该对象只有一个如何通过连接c3p0数据库连接池获得数据库连接:首先需要c3p0的jar包...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,678
精华内容 671
关键字:

数据库连接池线程池