首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >设置一个Fiveton类,以供不同的线程以循环方式访问

设置一个Fiveton类,以供不同的线程以循环方式访问
EN

Stack Overflow用户
提问于 2013-04-10 15:42:35
回答 3查看 589关注 0票数 2

类似于Singleton类,我想创建一个Fiveton类,它可以创建类的最多5个实例。不同的线程正在尝试访问该类的实例(因此需要提供getInstance方法)。然而,类很重,所以不能急于创建实例,即按需创建实例。

另一个约定是线程以循环方式分配实例,即线程编号1、6、11获取Fiveton对象的实例1。如果实例正被线程使用,则它们等待锁(线程6和11可能等待实例1,线程11可能获得它,但在任何情况下线程11都不应该获得实例2)。类似地,第2、7、12号线程应该获得实例2。

EN

回答 3

Stack Overflow用户

发布于 2013-04-10 16:16:25

不要在你的类本身中编写代码,而是使用对象池。

Apache Commons / Pool是一个很好的入门库

另一个我不知道,但声称更快的是furious-objectpool

使用提供的实现之一或使用这些库作为构建您自己的定制池的基础。

*为什么不将其编码到类本身中?因为类做什么以及如何访问类的实例都是无关的问题。这个类应该专注于它的核心目的,而不是管理自己。

票数 3
EN

Stack Overflow用户

发布于 2013-04-10 22:19:08

如果您在创建实例时关心争用(即,您不希望Thread6阻塞,因为Thread2仍在创建其实例),则可以使用锁剥离策略-在此实现中,假设Thread1,2,...依次调用getInstance

代码语言:javascript
运行
复制
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;
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2013-04-10 16:28:56

如果我正确理解了您的要求,您可以尝试如下所示:

代码语言:javascript
运行
复制
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指出的那样,你可以使用它来管理实例,并为你想要的逻辑创建一个不同的类(对象),这样它就更干净和透明了。

更新

添加了延迟初始化

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15919839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档