本文介绍: 池化技术是一种很常见编程技巧,目的在于提前创建内存对象线程资源,降低程序运行时频繁的创建销毁带来的开销。常见的有线程池,内存池,对象池等。池化技术如何高性能,降低系统开销在实际的应用中,程序经常需要创建对象线程分配内存。这些设计系统调用系统调用会导致程序用户态到内核态的切换比较耗时。有了池化技术需要用到对应线程对象和内存时不需要切换上下文需要从相应的池中获取,也不需要销毁,用完归还即可线程实现原理

什么池化技术

池化技术是一种很常见编程技巧,目的在于提前创建如内存,对象线程资源,降低程序运行时频繁的创建销毁带来的开销。常见有线程池,内存池,对象池等。

池化技术如何高性能,降低系统开销

在实际的应用中,程序经常需要创建对象,线程和分配内存。这些设计到系统调用系统调用会导致程序从用户态到内核态的切换比较耗时。有了池化技术,需要用到对应的线程,对象和内存时不需要再切换上下文之需要从相应的池中获取,也不需要销毁,用完归还即可

线程池实现的原理

启动若干线程让其处于休眠状态/当用户中的系统需要访问时,从线程池中拿出一个已建立的空闲连接使用完毕后不关闭连接而是归还到线程池中。

数据库连接池的重要配置最大连接数最小连接数

线程池的重要配置核心线程数,最大线程数

对象

一个对象池需要考虑的:

示例
1 对象池接口

public interface HousePool {
    // 创建
    House getHouse();
    // 归还
    void release(House po);
    //初始化
    void init();
}

具体实现

@Service
public class HousePoolImpl implements HousePool{
    // 维护两个池子
    private LinkedBlockingQueue<House> idle ;
    private LinkedBlockingQueue<House> busy ;
    //维护池中的对象数量
    private final  int maxSize = 10 ;
    private AtomicInteger busySize = new AtomicInteger(0) ;

    @Override
    public void init() {
         idle = new LinkedBlockingQueue<>();
         busy = new LinkedBlockingQueue<>();
    }

    @Override
    public House getHouse() {
        // 创建对象
        House po = null;
        po = idle.poll();
        // 有空闲对象 直接
        if(po != null){
            busy.offer(po);
            return po;
        }
        // 未满 创建
        if(busySize.get() < maxSize){
            if(busySize.incrementAndGet() <= maxSize){
                System.out.println("创建House");
                po = new House();
                busy.offer(po);
                return po;
            }
        }
        // 已满等待超时报错
        try {
            idle.poll(10000, TimeUnit.MILLISECONDS);
            if(po ==null){
                   throw  new RuntimeException("超时");
            }
            busy.offer(po);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return po;
    }

    @Override
    public void release(House po) {
        busy.remove(po);
        idle.offer(po);
    }
}

初始化配置

@Configuration
public class PoolConfiguration {

    @Bean
    public  HousePool housePool(){
        HousePoolImpl housePool = new HousePoolImpl();
        housePool.init();
        return housePool;
    }
}

代码解读:
为什么使用LinkedBlockingQueue作为对象池化容器
1 容量可选:可以选择指定容量,也可以指定,不指定时容量为Integer.MAX_VALUE。
2 公平性选择可以选择是否公平地对等待生产者消费者进行排序
3 阻塞操作:当队列为空时,消费者会被阻塞直到队列非空;当队列满时,生产者会被阻塞直到队列有空间
4 线程安全

如何解决多线程环境下对同一个空闲对象的竞争

 private AtomicInteger busySize = new AtomicInteger(0) ;
  if(busySize.get() < maxSize){
        if(busySize.incrementAndGet() <= maxSize){
           System.out.println("创建House");
            po = new House();
            busy.offer(po);
            return po;
         }
   }

解决池满后等待问题

// 已满等待超时报错
        try {
            idle.poll(10000, TimeUnit.MILLISECONDS);
            if(po ==null){
                   throw  new RuntimeException("超时");
            }
            busy.offer(po);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

测试

 @Test
    void testOrigin() {
        housePool.init();
        int i = 0 ;
        while(i < 10){
            House house = housePool.getHouse();
            System.out.println("得到hosue");
            housePool.release(house);
            i++;
        }
    }

结果在这里插入图片描述

可以看到对象只创建了一次,被使用多次

原文地址:https://blog.csdn.net/weixin_43747389/article/details/134786558

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_39048.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注