程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java中設計一個簡單的對象池

java中設計一個簡單的對象池

編輯:關於JAVA

1. 對象池

當調用對象時,不使用常規的new 構造子的方式,而是通過一 個對象池操作。即如果池中存在該對象,則取出;如果不存在,則 新建一個對象並存儲在池中。當使用完該對象後,則將該對象的歸 還給對象池。

這裡會存在幾個問題,必須注意。

Tips 1,考慮多線程狀態下的存取對象;

Tips 2,考慮將對象池目錄表設計為Singleton模式,這樣使得 內存中僅存在唯一的一份緩存對象的表。

2.對象單元設計

每個對象單元指定一種類型的對象,由Class<T> type維 護。對象單元有兩個List,List<T> items用於存放該類型 的同類對象,List<Boolean> checkedOut用於指定當前是否 可用。

設置信號量int semaphore,當semaphore < items.size() 說明目前List中還有“空閒”的對象。每次取出對象後需 semaphore++,歸還對象後需semaphore--。

對象單元ObjectUnit.java

import java.util.ArrayList;
import java.util.List;
public class ObjectUnit<T> {
   private Class<T> type;
   private List<T> items = new ArrayList<T>();
   private List<Boolean> checkedOut = new ArrayList<Boolean>();
   private int semaphore;
   public ObjectUnit(Class<T> type) {
    this.type = type;
   }
   public synchronized T addItem() {
    T obj;
    try {
      obj = type.newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    items.add(obj);
    checkedOut.add(false);
    return obj;
   }
   public synchronized T checkOut() {
    if (semaphore < items.size()) {
      semaphore++;
      return getItem();
    } else
      return addItem();
   }
   public synchronized void checkIn(T x) {
    if (releaseItem(x))
      semaphore--;
   }
   private synchronized T getItem() {
    for (int index = 0; index < checkedOut.size(); index++)
      if (!checkedOut.get(index)) {
        checkedOut.set(index, true);
        return items.get(index);
      }
    return null;
   }
   private synchronized boolean releaseItem(T item) {
    int index = items.indexOf(item);
    if (index == -1)
      return false; // Not in the list
    if (checkedOut.get(index)) {
      checkedOut.set(index, false);
      return true;
    }
    return false;
   }
}

3.對象池目錄表設計

使用Map<Class<?>, ObjectUnit<?>>來保 存當前對象池中類型目錄,並把它設計為線程安全的 ConcurrentHashMap。

這裡的getObj方法和renObj方法不用加鎖,因為它調用的對象 單元類是線程安全的,並且Map是線程安全的。

此外,這裡在處理泛型的時候,會有warning產生,因為之前定 義Map中使用<?>,而後面的兩個泛型方法指定<T>。 還沒有想到更好的解決辦法。

Provider.java

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Provider {
   private Map<Class<?>, ObjectUnit<? >> providers = new ConcurrentHashMap<Class<? >, ObjectUnit<?>>();
   private static Provider instance = new Provider ();
   private Provider() {
   }
   public static Provider getInstance() {
    return instance;
   }
   @SuppressWarnings("unchecked")
   public <T> T getObj(Class<T> key) {
    ObjectUnit value = providers.get(key);
     if (value != null) {
      return (T) value.checkOut();
    } else {
      value = new ObjectUnit<T>(key);
      providers.put(key, value);
      return (T) value.addItem();
    }
   }
   @SuppressWarnings("unchecked")
   public <T> void renObj(T x) {
    if (providers.containsKey(x.getClass())) {
      ObjectUnit value = providers.get(x.getClass ());
      value.checkIn(x);
    }
   }
}

本文出自 “子 孑” 博客,請務必保留此出處

http://zhangjunhd.blog.51cto.com/113473/66059

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved