类似于Singleton类,我想创建一个Fiveton类,它可以创建类的最多5个实例。不同的线程正在尝试访问该类的实例(因此需要提供getInstance方法)。然而,类很重,所以不能急于创建实例,即按需创建实例。
另一个约定是线程以循环方式分配实例,即线程编号1、6、11获取Fiveton对象的实例1。如果实例正被线程使用,则它们等待锁(线程6和11可能等待实例1,线程11可能获得它,但在任何情况下线程11都不应该获得实例2)。类似地,第2、7、12号线程应该获得实例2。
发布于 2013-04-10 16:16:25
不要在你的类本身中编写代码,而是使用对象池。
Apache Commons / Pool是一个很好的入门库
另一个我不知道,但声称更快的是furious-objectpool
使用提供的实现之一或使用这些库作为构建您自己的定制池的基础。
*为什么不将其编码到类本身中?因为类做什么以及如何访问类的实例都是无关的问题。这个类应该专注于它的核心目的,而不是管理自己。
发布于 2013-04-10 22:19:08
如果您在创建实例时关心争用(即,您不希望Thread6阻塞,因为Thread2仍在创建其实例),则可以使用锁剥离策略-在此实现中,假设Thread1,2,...依次调用getInstance
:
class CyclicFiveton {
private static final CyclicFiveton[] fivetons = new CyclicFiveton[5];
private static final Object[] locks = new Object[5];
private static final AtomicInteger counter = new AtomicInteger();
static {
for (int i = 0; i < 5; i++) {
locks[i] = new Object();
}
}
private CyclicFiveton() {
}
public static CyclicFiveton getInstance() {
int index = counter.getAndIncrement() % 5;
synchronized (locks[index]) {
CyclicFiveton fiveton = fivetons[index];
if (fiveton == null) {
fiveton = new CyclicFiveton();
fivetons[index] = fiveton;
}
return fiveton;
}
}
}
发布于 2013-04-10 16:28:56
如果我正确理解了您的要求,您可以尝试如下所示:
public class Fiveton {
private Fiveton(){
//create private constructor to prevent new instances from outside of the class
}
private static final int MAX_NB_INSTANCES = 5;
private static List<Fiveton> instances;
/**
* Should be called once at the beginning
*/
public static void init(){
instances = new ArrayList<Fiveton>(MAX_NB_INSTANCES);
for(int i=0;i<MAX_NB_INSTANCES;i++){
instances.add(new Fiveton());
}
}
/**
* threadNb can be the name of the Thread::getName()
*
* @param threadNb
* @return Fiveton
*/
public static Fiveton getInstance(int threadNb){
synchronized(instances.get(threadNb%MAX_NB_INSTANCES)){
return instances.get(threadNb%MAX_NB_INSTANCES);
}
}
/**
* other logic
*
*/
}
您所需要做的就是添加Fiveton对象背后的逻辑。
更新
或者,正如Sean Patrick Floyd指出的那样,你可以使用它来管理实例,并为你想要的逻辑创建一个不同的类(对象),这样它就更干净和透明了。
更新
添加了延迟初始化
https://stackoverflow.com/questions/15919839
复制相似问题