Java中池化技术探讨

文章介绍了Java中的池化技术,包括内存池通过Netty的例子,线程池确保性能稳定的方法,以及对象池如JedisPool的性能测试。通过使用池化技术,可以显著提高资源利用率,减少创建和销毁的开销,提升系统性能。此外,文章还涉及了连接池在Web请求和Druid组件中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:在日常开发中,除了考虑IO操作、线程上下文切换、GC的影响性能外。还通过池化技术提高性能通过循环复用资源,降低资源创建和销毁带来的开销和损失,从而提高性能,例如对象池、内存池、线程池、连接池

一、内存池(netty4举例 时间有限后续补充)

        内存池技术原理:【池化技术】内存池技术原理和C语言实现_小熊coder的博客-优快云博客

  

二、线程池

        线程池技术原理想必都知道,这里不赘述       

   集成多线程怎么保证以下两点:

        1、性能稳:怎样保证不知道业务量总数情况下采用多线程 线程队列池:

                java.util.Queue 线程隔离器:

                CyclicBarrier 或 CountDownLatch

                锁

                任务执行器(对外)

        2、逻辑稳:怎样使改造后逻辑出错率接近为0

                逻辑侵入 接近 0

/*
 * 线程处理接口
 * */
public interface ThreadFacade<T, R> {
    /*
     * 返回任务集合
     * */
    public List<R> execute(List<T> task);
}

/*
* 任务执行器
* */
public interface TaskThreadFacade<T,R> {
    //任务执行
    R execute(T t);
}
public class ThreadTemplate<T,R> implements TaskThreadFacade<T,R> {

    /*
    * 多线程任务构造器:在这里构造所任务信息
    * */
    public  List<R> batchExecute(List<T>task){
        ThreadFacade<T,R> threadService = new ThreadFacadeImpl<T,R>(this,8);
        return threadService.execute(task);
    }

    /*
    * 任务实现器:在这里处理需要执行的任务
    * */
    @Override
    public R execute(T t) {
        return null;
    }
}

--业务调用实现

--1、原来循环代码
List<Object> resultList = new LinkedList<>();
for(Object item:ObjectList){
    
     Object result = ...省略任务执行内容
     resultList.add(result);
}

--2、改造后代码
List<Object> resultList = ThreadTemplate.batchExecute(ObjectList);

改造前:批量审核20份以上报告,耗时都比较久。45份耗时33秒,92份耗时67秒,110份耗时72秒

改造后:100份报告耗时8秒

出错率:0次

三、对象池(JedisPool举例) 

        1、jedis对象池和非对象池测试用例对比,使用池化技术很大提高OPS性能,测试如下     

package com.sk.pool.memory;

import com.sk.util.DateTimeUtils;
import org.openjdk.jmh.annotations.*;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Warmup(iterations = 5, time = 1)//预热 5 轮,每次 1s
@Measurement(iterations = 5, time = 1)//测试 5 轮,每次 1s
@Fork(2)//2个线程
@State(Scope.Benchmark)
public class RedisTest {
    JedisPool pool = new JedisPool("172.17.1.150", 6379);

    @Benchmark
    public void redisPool() {
        Jedis jedis = pool.getResource();
        jedis.auth("***");
        jedis.set("value", DateTimeUtils.getCurrentDateTime());
        jedis.close();
    }

    @Benchmark
    public void redisSimple() {
        Jedis jedis = new Jedis("172.17.1.150", 6379);
        jedis.auth("***");
        jedis.set("value", DateTimeUtils.getCurrentDateTime());
        jedis.close();
    }
}

        pom.xml引用文件

    <dependencies>
        <!-- jhm工具包 -->
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>1.21</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>1.21</version>
            <scope>provided</scope>
        </dependency>

        <!--redis工具包-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.1</version><!--版本号-->
        </dependency>
    </dependencies>

        JMH结果为

         2、reids对象池管理分析

        Jedis jedis = pool.getResource();

--main入口
Jedis jedis = pool.getResource();


--pool class
public T getResource() {
    try {
      return internalPool.borrowObject();
    } catch (Exception e) {
      throw new JedisConnectionException("Could not get a resource from the pool", e);
    }
  }

--GenericObjectPool class
public T borrowObject(final Duration borrowMaxWaitDuration) throws Exception {
        ...省略

        PooledObject<T> p = null;
        boolean create;
        while (p == null) {
            create = false;
            //对象池获取对象
            p = idleObjects.pollFirst();
            if (p == null) {
                //对象池未获取到,创建对象
                p = create();
                if (p != null) {
                    create = true;
                }
            }
            
        ...省略

        return p.getObject();
    }


private PooledObject<T> create() throws Exception {
        ...省略
        final PooledObject<T> p;
        try {
            p = factory.makeObject();
        ...省略
        return p;
    }

--jedisFactory class
public PooledObject<Jedis> makeObject() throws Exception {
    final HostAndPort hostAndPort = this.hostAndPort.get();
    final Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), this.timeout);
    --redis连接
    jedis.connect();
    if (null != this.password) {
      jedis.auth(this.password);
    }
    if (database != 0) {
      jedis.select(database);
    }
    if (clientName != null) {
      jedis.clientSetname(clientName);
    }
    --返回reids连接对象
    return new DefaultPooledObject<Jedis>(jedis);
  }

        对象池管理工具类GenericObjectPool依赖Java公用的池化包commons-pool2实现对象池化管理

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.11.1</version>
</dependency>

        3、对象池管理生命周期,参数设置建GenericObjectPoolConfig

        

转载:面试官:Java 池化技术你了解多少?_肥肥技术宅的博客-优快云博客

四、连接池(web请求和druid组件)

        1)、web请求伪代码       

public static String callWebservcie(String urlKey, String url,String interfaceName,Object[] params) {
		String result = "";
		Client client = null;
		// 创建动态客户端
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		if (!mapHiswebservice.containsKey(urlKey)) {
			client = dcf.createClient(url);
			mapHiswebservice.put(urlKey, client);
		}else{
			client =mapHiswebservice.get(urlKey);
		}
		// 需要密码的情况需要加上用户名和密码
		// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,
		// PASS_WORD));
		try {
			Object[] resultBacks = client.invoke(interfaceName,params);
			if (resultBacks != null && resultBacks.length > 0) {
				result = resultBacks[0].toString();
			}
		} catch (Exception e) {
			logger.error("原因[{}]异常,异常信息[{}],参数[{}]",
					"Webservice调用异常",
					e.getMessage(),
					JSONArray.toJSON(params),
					e);
			throw new RuntimeException(e);
		}
		return result;
	}

                2)、druid

        https://mp.youkuaiyun.com/mp_blog/creation/editor/130554085?not_checkout=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值