Java实时数据处理之三-池化技术(线程池 & 对象池)

一、线程池使用步骤:

1、自定义线程池

private ThreadPoolExecutor executor;

    /**
     * 初始化线程池
     */
    @PostConstruct
    private void init(){
        int processors = Runtime.getRuntime().availableProcessors();
        int corePoolSize = processors * 2;
        LinkedBlockingQueue queue = new LinkedBlockingQueue();
        // 自定义线程池
        executor = new ThreadPoolExecutor(corePoolSize, corePoolSize * 2,
                60, TimeUnit.SECONDS, queue, new ThreadPoolDemoFactory("demo"));
        log.info("CorePoolSize: {}", executor.getCorePoolSize());
        log.info("MaximumPoolSize: {}", executor.getMaximumPoolSize());

    }
View Code

2、给多线程构造任务

   /**
     * 使用多线程,批量插入数据到MySql
     */
    @RequestMapping("/")
    private void batchSave2MySql() throws SQLException {
        // 创建一个存储CompletableFuture的数组,存储异步调用的对象
        List<CompletableFuture<?>> futures = new ArrayList<>(1000000);
        Connection conn = MySqlUtils.getConn();
        Device device1 = new Device();
        Device device2 = new Device();
        device1.setName("device1");
        device1.setTypeId(1);
        device2.setName("device2");
        device2.setTypeId(2);
        List<Device> list = Lists.newArrayList();
        list.add(device1);
        list.add(device2);
        // 给多线程构造任务
        for(Device device : list){
            PreparedStatement stmts = conn.prepareStatement
                    ("insert into device values(?,?,?)");
            stmts.setString(1, UUID.randomUUID().toString());
            stmts.setString(2, device.getName());
            stmts.setInt(3, device.getTypeId());
            // 多线程执行后的返回结果在哪??
            CompletableFuture future = CompletableFuture.supplyAsync(() -> {
                try {
                    return stmts.execute();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }, executor);
            futures.add(future);
        }

    }
View Code

3、多线程执行(自动)

git:https://gitee.com/caesarthegreat/thread-pool-demo.git

 

二、对象池使用步骤:

引入依赖:

<!-- 对象池 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.11.1</version>
        </dependency>

 

1、自定义工厂类继承BasePooledObjectFactory

@Slf4j
public class ObjPoolFactory extends BasePooledObjectFactory<Connection> {


    private static String driverName = "com.mysql.cj.jdbc.Driver";
    public static String url = "jdbc:mysql://localhost:3306/test?useUnicode=true" +
            "&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
    public static String user = "root";
    public static String password = "12345";

    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static volatile Connection conn = null;

    // 对象池
    private static volatile GenericObjectPool<Connection> pool = null;

    public static GenericObjectPool<Connection> getObjPool(){
        if(pool == null){
            synchronized (ObjPoolFactory.class){
                if(pool == null){
                    int processors = Runtime.getRuntime().availableProcessors();
                    GenericObjectPoolConfig<Connection> config = new GenericObjectPoolConfig<>();
                    config.setMaxTotal(-1);
                    config.setMaxIdle(processors * 2 * 2);
                    config.setMinIdle(processors * 2);
                    config.setLifo(false);
                    pool = new GenericObjectPool<>(new ObjPoolFactory(), config);

                    log.info("连接池中对象数量:{}", pool.getNumActive());
                }
            }
        }
        return pool;
    }

    /**
     * 借用对象
     * @return
     * @throws Exception
     */
    public static Connection borrowObj() throws Exception {
        return getObjPool().borrowObject();
    }

    /**
     * 归还对象
     * @param connection
     * @throws Exception
     */
    public static void returnObj(Connection connection) throws Exception {
        getObjPool().returnObject(connection);
    }

    /**
     * 创建对象
     * @return
     * @throws Exception
     */
    @Override
    public Connection create() throws Exception {
        Class.forName(driverName);
        Connection conn = DriverManager.getConnection(url, user, password);
        return conn;
    }

    @Override
    public PooledObject<Connection> wrap(Connection connection) {
        return new DefaultPooledObject<>(connection);
    }

    /**
     * 销毁对象
     * @param p
     * @param destroyMode
     * @throws Exception
     */
    @Override
    public void destroyObject(PooledObject<Connection> p, DestroyMode destroyMode) throws Exception {
        super.destroyObject(p, destroyMode);
    }
}
View Code

2、借用和归还对象

@RequestMapping("/")
    private void batchSave2MySql() throws Exception {
        // 创建一个存储CompletableFuture的数组,存储异步调用的对象
        List<CompletableFuture<?>> futures = new ArrayList<>(1000000);
        //Connection conn = MySqlUtils.getConn();
        Device device1 = new Device();
        Device device2 = new Device();
        device1.setName("device3");
        device1.setTypeId(3);
        device2.setName("device4");
        device2.setTypeId(4);
        List<Device> list = Lists.newArrayList();
        list.add(device1);
        list.add(device2);
        Connection conn = null;
        try {
            // 使用对象池中的对象
            conn = ObjPoolFactory.borrowObj();
            // 给多线程构造任务
            for(Device device : list){
                PreparedStatement stmts = conn.prepareStatement
                        ("insert into device values(?,?,?)");
                stmts.setString(1, UUID.randomUUID().toString());
                stmts.setString(2, device.getName());
                stmts.setInt(3, device.getTypeId());
                // 多线程执行后的返回结果在哪??
                CompletableFuture future = CompletableFuture.supplyAsync(() -> {
                    try {
                        return stmts.execute();
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                }, executor);
                futures.add(future);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 归还对象池中的对象
            ObjPoolFactory.returnObj(conn);
        }

    }
View Code

git:https://gitee.com/caesarthegreat/thread-pool-demo.git

posted @ 2023-01-22 18:40  Caesar_the_great  阅读(300)  评论(0编辑  收藏  举报