首页 > 其他分享 >单体应用提高性能和处理高并发-资源管理连接池

单体应用提高性能和处理高并发-资源管理连接池

时间:2024-08-10 12:52:48浏览次数:12  
标签:java 数据库 并发 线程 import config 资源管理 连接池

在单体应用中,资源管理是提高性能和处理高并发的重要方面。资源管理通常涉及到数据库连接、线程管理等,这些资源如果管理不当,会导致系统性能下降甚至崩溃。连接池和线程池是两个常用的资源管理手段,能够显著提高资源的复用性,减少频繁创建和销毁资源的开销。

1. 数据库连接池

数据库连接池是管理数据库连接的常用方式,它通过预先创建一定数量的数据库连接,存放在池中供应用程序复用,从而避免每次访问数据库时都需要重新建立连接的开销。这不仅能提高应用的性能,还能减少数据库服务器的负担。

1.1 使用HikariCP连接池

HikariCP是一个高效的JDBC连接池,广泛用于Java应用中。以下是一个使用HikariCP管理数据库连接的实例:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class HikariCPExample {
    private static HikariDataSource dataSource;

    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(10); // 设置最大连接数
        config.setMinimumIdle(5); // 设置最小空闲连接数

        dataSource = new HikariDataSource(config);
    }

    public static void main(String[] args) {
        try (Connection connection = dataSource.getConnection();
             Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

            while (rs.next()) {
                System.out.println("User ID: " + rs.getInt("id") + ", Username: " + rs.getString("username"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,HikariCP通过配置预先创建了一定数量的数据库连接(最大10个,最小5个),这些连接会被保存在连接池中,供应用程序复用。当应用程序需要访问数据库时,可以从池中获取连接,而不是每次都新建连接,这大幅度提升了数据库操作的效率。

1.2 使用Spring Boot中的连接池

在Spring Boot中,数据库连接池的配置更加简便,Spring Boot默认集成了HikariCP,开发者可以通过简单的配置来管理连接池。

# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb
    username: root
    password: password
    hikari:
      maximum-pool-size: 10
      minimum-idle: 5

使用上述配置,Spring Boot应用会自动创建和管理HikariCP连接池,应用程序无需显式管理连接,提升了开发效率。

2. 线程池

线程池是一种线程管理机制,通过预先创建一定数量的线程放入池中供应用程序复用,避免了频繁创建和销毁线程所带来的开销。线程池广泛用于多线程编程,尤其是在需要并发处理大量任务的场景中。

2.1 使用Java中的线程池

Java标准库提供了ExecutorService接口和ThreadPoolExecutor类来管理线程池。以下是一个使用线程池处理并发任务的示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5); // 创建固定大小的线程池

        for (int i = 0; i < 10; i++) {
            int taskId = i;
            executorService.submit(() -> {
                System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        executorService.shutdown(); // 关闭线程池
    }
}

在这个示例中,Executors.newFixedThreadPool(5)创建了一个包含5个线程的固定大小线程池。10个任务通过submit方法提交到线程池中,线程池会复用这5个线程来处理任务,从而避免了频繁创建和销毁线程的开销。

2.2 Spring中的线程池管理

在Spring应用中,线程池的管理可以通过@Async注解和ThreadPoolTaskExecutor来实现。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("AsyncTask-");
        executor.initialize();
        return executor;
    }
}

public class AsyncService {

    @Async("taskExecutor")
    public void performTask(int taskId) {
        System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000); // 模拟任务执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,ThreadPoolTaskExecutor被配置为Spring管理的线程池,@Async注解用于将performTask方法的执行异步化。当调用该方法时,Spring会从线程池中获取一个线程来执行任务,从而提升系统的并发处理能力。

3. 连接池与线程池结合使用

在实际项目中,数据库连接池与线程池往往需要结合使用,尤其是在需要同时处理大量数据库请求的高并发场景中。

3.1 Java中的连接池与线程池结合使用

以下是一个使用HikariCP连接池和Java线程池的结合实例,展示如何在并发环境下高效管理数据库连接:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CombinedExample {
    private static HikariDataSource dataSource;

    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(10);

        dataSource = new HikariDataSource(config);
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        for (int i = 0; i < 10; i++) {
            executorService.submit(() -> {
                try (Connection connection = dataSource.getConnection();
                     Statement stmt = connection.createStatement();
                     ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

                    while (rs.next()) {
                        System.out.println("User ID: " + rs.getInt("id") + ", Username: " + rs.getString("username"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }

        executorService.shutdown();
    }
}

在这个示例中,HikariCP管理数据库连接,Java线程池管理线程。10个并发任务通过线程池提交,每个任务从连接池中获取一个数据库连接来执行查询操作。连接池和线程池的结合使用,不仅提高了资源的利用率,还确保了高并发场景下系统的稳定性和性能。

总结

通过上述实例,我们可以看到,连接池和线程池是提高单体应用性能和处理高并发的重要工具。连接池通过复用数据库连接,减少了频繁创建和销毁连接的开销,提升了数据库操作的效率;线程池通过复用线程资源,避免了频繁创建和销毁线程的开销,提高了系统的并发处理能力。在实际项目中,合理配置和使用这些资源管理工具,能够显著提升应用的性能和稳定性。

标签:java,数据库,并发,线程,import,config,资源管理,连接池
From: https://blog.csdn.net/chenkun_321/article/details/141089141

相关文章

  • [Java并发]ThreadLocal补充
    ThreadLocal缺点及解决方案每个Thread上都有一个threadLocals属性,它是一个ThreadLocalMap,里面存放着一个Entry数组,key是ThreadLocal类型的弱引用,value是对用的值。所有的操作都是基于这个ThreadLocalMap操作的。但是它有一个局限性,就是不能在父子线程之间传递。即在子线程中无......
  • 并发编程(第一天)
    进程与线程进程程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。......
  • kubernetes笔记-4-kubernetes资源管理
    一、、kubernetes资源分类:工作负载、发现与负载均衡、配置与存储、集群、和元数据1、工作负载型资源分为:有状态和无状态两种类型;无状态:每个pod均可被其它其他同类所取代;有状态:有其独特性,必须单独标识和管理;ReplicaSet、Deployment负责无状态应用管理;StatefulSet负责有状态应用管......
  • 如何把Connection 封装到工具类里面 调用工具类方法实现 增删改查操作 java JDBC
    如何把Connection封装到工具类里面调用工具类方法实现增删改查操作javaJDBC使用数据库连接池以HikariCP为例在JDBC中,使用数据库连接池是一个常见的做法,以提高数据库操作的效率和性能。连接池管理着一组数据库连接,这些连接可以被重用而不是每次需要时都创建新的连接。......
  • 如何把Connection 封装到工具类里面 调用工具类方法实现 增删改查操作 java JDBC使用
    如何把Connection封装到工具类里面调用工具类方法实现增删改查操作javaJDBC使用C3P0数据库连接池答:当使用C3P0作为数据库连接池时,你可以按照类似的模式来配置和使用它。以下是一个示例,展示了如何在Java项目中配置C3P0连接池,并创建一个工具类来管理数据库连接和执行基本的......
  • sentinel限流并发线程数限流 与 直接QPS限流 区别
    发线程数限流和直接QPS限流是Sentinel中两种不同的限流策略,它们分别从不同的角度来控制系统的流量和负载。下面详细解释这两种限流的区别:并发线程数限流(ConcurrencyLevelThreshold)定义:并发线程数限流关注的是某一时刻正在执行的请求的数量。当一个请求开始执行并......
  • 【c++】Linux MySQL连接池
    #ifndefMYSQLCONNECTION_H#defineMYSQLCONNECTION_H#include<iostream>#include<mysql.h>#include<vector>classMySQLConnection{public: ///<summary> ///初始化连接 ///</summary> MySQLConnection(); MySQLConnection(MySQ......
  • 一文搞定:LLM并发加速部署方案(llama.cpp、vllm、lightLLM、fastLLM)
    llama.cpp、vllm、lightllm、fastllm四种框架的对比:llama.cpp:基于C++,①请求槽,②动态批处理,③CPU/GPU混合推理vllm:基于Python,①PagedAttention高效管理注意力KV内存,②连续动态批处理,③量化GPTQ/AWQ/SqueezeLLM等。lightllm:基于Python,①三进程异步协作,②动态批处理,③Fla......
  • Python并发编程
    简介多线程:threading,利用cpu和io可以同时执行的原理,让CPU不会等待IO完成多进程:multiprocess,利用多核CPU的能力,真正的并行执行任务异步IO:asynio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行 使用Lock对共享资源加锁,防止冲突访问使用Queue实现不......
  • Java并发编程——线程创建的4种常见方式
    文章目录一、继承Thread类创建创建线程类1.1Thread类解析1.2使用方法1.3优缺点二、实现Runable接口创建线程类2.1Runable接口解析2.2使用方法2.3优缺点三、使用Callable和FutureTask创建线程3.1Callable接口解析3.2RunnableFuture接口解析3.3Futu......