aquarius Java自定义对象池

背景说明

上周五在项目里码代码时遇到一个需求,需要开启一个DatagramSocket端口去接收数据。

开始用的内部类的单例模式,后来觉得一个端口不得劲,就创建了多个DatagramSocket实例端口放到list里(这里不用队列是考虑连接是否可以重用,队列一般用于不可重用),然后用随机取出连接。

博主毛病多,后面又想去做一个负载均衡取对象,但是中途放弃了,哈哈哈哈

由于之前多次遇到类似的连接型的需求,索性先设计一个便捷生成指定对象的对象池的小框架,后面慢慢自己扩展负载算法

项目结构

  • tonatyw.pool.aquarius
    • annotation
      BalanceFactory.java
      HashBalance.java
      • handle
        HashBalance.java
        • base
          Balance.java
    • constants
      Sets.java
    • util
      ReflectUtil.java

util: 工具包
constants: 常量包
annotation: 注解类的包,里面可自行定义扩展算法
handle: 算法实现这里面的实现需要继承Balance
base: 算法接口同时也是一个对外的池对象

使用范围

本地项目中各种的连接对象或者是其他的需要使用池概念的对象

基本使用

单参数

public class HashBalanceDemo {
	@HashBalance(clas=DatagramSocket.class,str={"8081","8082","8083"},paramType={int.class})
	public static Balance<DatagramSocket> sockets;
	public static void main(String[] args) {
		try {
			sockets = BalanceFactory.getInstance(HashBalanceDemo.class, "sockets");
			System.out.println(sockets.get());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

多参数

public class HashBalanceDemoTwo {
	@HashBalance(clas=InetSocketAddress.class,str={"127.0.0.1,8081","127.0.0.1,8082","127.0.0.1,8083"},paramType={String.class,int.class})
	public static Balance<InetSocketAddress> isa;
	public static void main(String[] args) {
		try {
			isa = BalanceFactory.getInstance(HashBalanceDemoTwo.class, "isa");
			System.out.println(isa.get().getPort());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

如何扩展

  1. 你需要在tonatyw.pool.aquarius.annatation下新建一个注解类 类名为a 类似如下
@Documented
@Target(ElementType.FIELD)
@Inherited
@Retention(RetentionPolicy.RUNTIME )
public @interface HashBalance{
	/** 散列对象 */
	Class clas();
	/** 对象实例化需要的参数 请使用{"a,b","c,d","e,f"}方式传入*/
	String[] str();
	/** 参数类型 */
	Class[] paramType();
}
  1. 然后在tonatyw.pool.aquarius.annatation.handle下写一个同名的类,类名也为a,名字必须相同。然后实现tonatyw.pool.aquarius.annatation.handle.base下的Balance接口,类似代码如下
public class HashBalance<T> implements Balance<T>{
	private List<T> list = new ArrayList<T>();

	public T get() {
		// hash散列算法
		BigDecimal longBd = new BigDecimal(System.currentTimeMillis());
		BigDecimal longSize = new BigDecimal(list.size());
		return (T) list.get(longBd.divideAndRemainder(longSize)[1].intValue());
	}
	public void init(Class<T> clas, Object[][] objs, Class[] paramsType) {
		try {
			Constructor con = clas.getConstructor(paramsType);
			// 拼装参数
			for(Object[] objArray:objs){
				list.add(clas.cast(con.newInstance((Object[])objArray)));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void release(T t) {
		
	}
}

由于Balance只提供了三个方法get、init和release,你需要根据自己的策略自己决定使用的对象容器,我这里使用的是可以共享使用的对象所以使用的list
对于不可重复使用的对象,有线程安全方面要求的对象,可以使用队列等去放入对象。

这些都写好后,就可以开始测试使用了,demo代码见上面基本使用部分。

待解决/完善问题

  1. 参数还不能在文件里配置
  2. 注解里必须写死,不能在外面用变量传进来,目前这里比较不满意,如果有大神有解决思路,请联系我。
  3. 是否有必要一个算法一个自定义注解,因为基本上每个自定义注解的参数都是不变的,可以做成一个注解根据传入参数定位handle里的算法实现。

下一次更新计划

  1. 增加加权轮询,最小连接数,加权随机负载算法的实现
  2. 增加文件配置支持
  3. 再多写点注释
  4. 本来想的能不能跟spring结合,在application里配置自定义对象池,考虑中。
  5. 看情况更新

这里是git地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值