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);
}
}
}
|
转载于:https://blog.51cto.com/zhangjunhd/66059