Java实时数据处理之三-池化技术(线程池 & 对象池)
一、线程池使用步骤:
1、自定义线程池
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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()); }
2、给多线程构造任务
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 使用多线程,批量插入数据到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); } }
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@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); } }
2、借用和归还对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@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); } }