java线程池和数据库连接池工作原理,两句话说清楚,附源码

线程池

创建线程池类,增加任务容器字段LinkedList集合泛型为<Runnable>线程接口.
构造器初始化创建10个线程并启动,集合为空的时候,所有线程等待.
当提交一个任务接口到任务容器LinkedList集合,就立刻唤醒等待的线程去抢任务,完成任务后并删除任务,继续去查看集合容器类有没有任务,如果没有就继续等待.

数据库连接池

连接池在使用之前,就会创建好一定数量的连接。
如果有任何线程需要使用连接,那么就从连接池里面借用,而不是自己重新创建.
使用完毕后,又把这个连接归还给连接池供下一次或者其他线程使用。
倘若发生多线程并发情况,连接池里的连接被借用光了,那么其他线程就会临时等待,直到有连接被归还回来,再继续使用。
整个过程,这些连接都不会被关闭,而是不断的被循环使用,从而节约了启动和关闭连接的时间。

/**
 * 自定义线程池
 */
public class ThreadPool {
    //线程大小
    int threadPoolSize;
    //Runnable接口类型容器
    LinkedList<Runnable> tasks = new LinkedList<Runnable>();

    //构造器初始化10个线程对象,并启动
    public ThreadPool(){
        threadPoolSize = 10;
        synchronized (tasks){
            for(int i=0;i<threadPoolSize;i++){
                new TaskConsumeThread("任务消费者线程 "+i).start();
            }
        }
    }

    //放入一个任务 并通知等待线程
    public void add(Runnable r){//传入一个接口对象Runnable
        synchronized(tasks){
            tasks.add(r);//创建该类对象 调用该方法 增加到任务容器中
            tasks.notifyAll();//唤醒该对象上的全部线程
        }
    }

    //线程
    class TaskConsumeThread extends Thread{
        public TaskConsumeThread(String name) {//构造器
            super(name);
        }
        Runnable task;//接口类型变量
        public void run(){
            System.out.println("启动:" + this.getName());
            while(true){
                synchronized(tasks){
                    while(tasks.isEmpty()){//如果此集合不包含任何元素,则返回 true
                        try {

                            tasks.wait();//使当前线程容器等待,直到它被唤醒,通常是通过 通知 或 中断
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    task = tasks.removeLast();//从此列表中删除并返回最后一个元素 取出一个任务接口
                    tasks.notifyAll();//唤醒此对象监视器上等待的所有线程
                }
                System.out.println(this.getName() + " 获取到任务,并执行");
                task.run();//抢到任务就执行
            }
        }
    }
}
/**
 * @author: BingKing
 * @Date: 2023/2/7 - 02 - 07 - 21:02
 * 自定义数据库连接池
 */
public class ConnectionPool {

    List<Connection> cs = new ArrayList<>();

    int size;

    public ConnectionPool(int size){
        this.size = size;
        init();//自动加载size数量的连接
    }

    /**
     * 类加载的时候 仅仅执行一次 创建size个连接
     */
    public void init(){
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/android",
                    "root","123456");

            cs.add(c);//放到连接集合里面
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 如果集合连接为空 就让当前对象等待 如果不为空 就取出来一个 并删除
     * @return
     */
    public synchronized Connection getConnection(){
        while(cs.isEmpty()){//如果集合为空 说明当前连接为空
            try{
                this.wait();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        Connection c = cs.remove(0);
        return c;
    }

    /**
     * 接收一个连接 添加到集合中 通知其他连接启动
     * @param c
     */
    public synchronized void returnConnection(Connection c){
        cs.add(c);
        this.notifyAll();
    }

}
/**
 * 测试使用线程池 和 数据库连接池
 * @author: BingKing
 * @Date: 2023/2/7 - 02 - 07 - 16:47
 */
public class ORM11 {

    public static void main(String[] args) {
        
        ThreadPool pool = new ThreadPool();//调用自定义线程池
        //数据库插入1000条数据
        for(int i=0;i<1000;i++){
            int i1 = i;
            pool.add(new Runnable() {
                @Override
                public void run() {
                    Heros h = new Heros();
                    h.name = "英雄 "+i1;
                    h.hp = 33.3f;
                    h.damage = 99;
                    add_pool(h);//调用自定义数据库连接池
                }
            });
        }
    }
    
    /**
     * @param heros 英雄对象
     * @return
     */
    public static void add_pool(Heros heros){

        String sql = "insert into heros value(null,?,?,?)";
        ConnectionPool pool = new ConnectionPool(10);// 数据库连接池启动 10个
        try(Connection c = pool.getConnection();//借一根
            PreparedStatement s = c.prepareStatement(sql);){
            s.setString(1,heros.name);
            s.setFloat(2,heros.hp);
            s.setInt(3,heros.damage);
            s.execute();
            pool.returnConnection(c);//还一根
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值