简单的java对象池(非阻塞)
jopen
11年前
之前在练习对象池,大致看了下commons.pool的代码,并不是用阻塞方法去得到对象,而是用一个循环一直去请求,据说这样效率要比阻塞的好很多。不知道是否用的什么循环CAS(啊啊啊,我是算法渣,待求证)
public class MyObjectPool2<T> { private int max = 5; private int min = 2; private long maxwait = 10000; //超时时间 private Class<? extends T> objclass; private ConcurrentLinkedQueue<T> pool = null; //未使用对象队列 private ConcurrentLinkedQueue<T> usedpool = null; private ReentrantLock lock = new ReentrantLock(); public MyObjectPool2(Class<? extends T> objclass){ this.objclass = objclass; } public void createPool(){ if(pool == null){ synchronized (this){ if(pool == null){ max = max >0 ? max : 5; min = min > 0 ? min : 0; pool = new ConcurrentLinkedQueue<T>(); //初始化 usedpool = new ConcurrentLinkedQueue<T>(); for(int i=0;i<min;i++){ try{ T obj = objclass.newInstance(); pool.add(obj); }catch (Exception e){} } } } } } public T get(){ T obj = null; long time = maxwait; boolean create = false; while(obj == null){ if(time <= 0) break; long temptime = System.currentTimeMillis(); obj = pool.poll(); if(obj == null){ obj = createObj(); create = true; if(obj == null){ temptime = System.currentTimeMillis() - temptime; time = maxwait - temptime; } } if(obj != null && !create){ if(!usedpool.contains(obj)) usedpool.add(obj); } } return obj; } public T createObj(){ T obj = null; lock.lock(); try{ if(pool.size() + usedpool.size() < max){ obj = objclass.newInstance(); usedpool.add(obj); } }catch (Exception e){ }finally { lock.unlock(); } return obj; } public void giveback(T obj){ if(obj == null) return; if(!pool.contains(obj)) pool.add(obj); usedpool.remove(obj); } public void distroy(){ } }
public static void main(String[] args) { final MyObjectPool2<User> pool = new MyObjectPool2(User.class); pool.createPool(); User u1 = pool.get(); User u2 = pool.get(); User u3 = pool.get(); User u4 = pool.get(); new Thread(new Runnable() { @Override public void run() { System.out.println("u5 start get"); User u5 = pool.get(); System.out.println("u5:" + u5); try{ TimeUnit.SECONDS.sleep(3);//模拟操作该对象 }catch(Exception e){} pool.giveback(u5); System.out.println("u5 giveback"); } }).start(); new Thread(new Runnable() { @Override public void run() { try{ TimeUnit.SECONDS.sleep(1); System.out.println("u6 start get"); User u6 = pool.get(); System.out.println("u6:" + u6); }catch(Exception e){} } }).start(); }
u5 start get u5:kyle.objectPool.User@1cf536e8 u6 start get u5 giveback u6:kyle.objectPool.User@1cf536e8