簡單的java對象池(非阻塞)

jopen 10年前發布 | 12K 次閱讀 Java開發 Java

    之前在練習對象池,大致看了下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



有時間一定嘗試只用一個隊列。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!