Java中的对象池模式 [英] Object Pool Pattern in Java

查看:130
本文介绍了Java中的对象池模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我已经实现了自己的对象池模式,它可以正常工作并且符合预期.从列表中返回我的教师"对象,并在没有对象时创建它们.

我的问题:返回的对象教师"然后需要转换为专门的子类之一,例如生物老师".

获得这种功能的最佳方法是什么?

抱歉,我认为不需要代码,但是可以了.

下面是我正在谈论的演员表.这引发了运行时异常,这是我的主要问题.

  final Bio-Teacher = (Bio-Teacher) ObjectPool.getTeacher();

这是我的getTeacher()方法中的代码.

 if (objectPool.size() > 0) {
        System.out.println("Object returned from list");
        return ObjectPool.remove(0);
    } else {
        System.out.println("Object made and returned");
        return new Teacher();
    }

目前,池中唯一的对象是教师",因此我只需要检查池中是否有对象.注意:我并没有跟踪正在使用的对象,只是跟踪池中的对象,这是需求的一部分,但是我很感谢您的建议.

解决方案

根据您要返回的内容,考虑具有多个对象池.如果您具有(请原谅我的命名)封装结构,该怎么办?

com.foo.bar.AbstractTeacher
com.foo.bar.Teacher // A factory
com.foo.bar.BioTeacher
com.foo.bar.PhysicsTeacher
...

这些类中的每一个都维护自己的对象池. BioTeacher仅包含BioTeacher,而Teacher包含所有Teacher对象.

因此,您将获得诸如以下的代码:

Teacher t = Teacher.getTeacher();
BioTeacher b = BioTeacher.getTeacher();

这将简化从更通用的池中进行转换的过程,因为您可以在获得教师之前指定所需的教师类型(尽管是的,这确实使Teacher类和BioTeacher类池之间的同步更加复杂).

可以通过制作包级方法来解决此问题(可以由同一包中的其他类调用(请注意com.foo.bar中所有类的方式),并且不能被该包外的对象调用

填充池将使用任一方法

Teacher.createTeacher(BioTeacher.class)

随后将在BioTeacher池中注册老师,或:

BioTeacher.createTeacher()

然后将在教师库中注册该老师.

如果在多线程环境中工作,则棘手的部分(由于这是一种学习经验,因此请牢记在方法Teacher.getTeacher()BioTeacher.getTeacher()中,其中方法可能具有竞争条件,其中一个线程会从中获得教师的帮助) getTeacher,而另一个线程从BioTeacher中获得一个线程.


对此的另一种方法(从上面忽略了多个构造函数的内容)是在Teacher类本身内维护Class,List<Teacher>的映射.当您要求一位老师(Teacher.getTeacher(Teacher.class)Teacher.getTeacher(BioTeacher.class))时,您可以在地图上查找该老师,并从相应的列表中返回一个项目.此外,在这种方法中(可以同步),您可以在其他列表中找到教师(该教师将始终在至少两个列表中(Teacher.class和BioTeacher.class)),并将其也从该列表中删除./p>

然后您可以编写代码,以便:

BioTeacher Teacher.getTeacher(BioTeacher.class)

无需其他转换即可工作.同样,这是一次学习体验,将使您进一步了解Java的泛型. (有关此方法的更多信息,请参见

My question: The object being returned "Teacher" then needs to be casted into one of its sub classes which is specialised e.g. "Biology-Teacher".

What is the best way to get this kind of functionality?

Edit: Sorry, I didn't think code was needed but here goes.

Below is the casting I was talking about. This throws a run-time exception which is my main problem.

  final Bio-Teacher = (Bio-Teacher) ObjectPool.getTeacher();

This is the code inside of my getTeacher() method.

 if (objectPool.size() > 0) {
        System.out.println("Object returned from list");
        return ObjectPool.remove(0);
    } else {
        System.out.println("Object made and returned");
        return new Teacher();
    }

At the moment the only objects in the pool are "Teachers" so I only need to check if there are any in the pool. Note: I'm not keeping track of the objects in use, just the ones in my pool, its part of the requirements but I appreciate the advice.

解决方案

Consider having multiple object pools depending on what you want to get back. What if you had the package structure of (and forgive me for the naming):

com.foo.bar.AbstractTeacher
com.foo.bar.Teacher // A factory
com.foo.bar.BioTeacher
com.foo.bar.PhysicsTeacher
...

Each of these classes maintains its own object pool. BioTeacher contains just BioTeacher, while Teacher contains all the Teacher objects

Thus, you would then have code such as:

Teacher t = Teacher.getTeacher();
BioTeacher b = BioTeacher.getTeacher();

This would simplify the casting from the more generic pool as you can specify what type of teacher you want before getting one (though yes, it does make the synchronization between the Teacher class and the BioTeacher class pools more complex).

The way this would be approached by making package level methods (they can be called by other classes in the same package (notice how all the classes are in com.foo.bar), and unable to be called by objects outside of that package.

Filling the pool would be done with either

Teacher.createTeacher(BioTeacher.class)

Which would then register the teacher in the BioTeacher pool or:

BioTeacher.createTeacher()

Which would then register the teacher in the Teacher pool.

The tricky part if working in a multithreaded environment (something to keep in mind as this is a learning experience is in the methods Teacher.getTeacher() and BioTeacher.getTeacher() where one would possibly have a race condition where one thread gets the Teacher from getTeacher while another thread gets one from the BioTeacher.


Another approach to this (forget about the stuff of multiple constructors from above) is to maintain a map of Class,List<Teacher> within the Teacher class itself. When you ask for a teacher (Teacher.getTeacher(Teacher.class) or Teacher.getTeacher(BioTeacher.class)) you look it up in the map and return an item from the appropriate list. Furthermore, in this method (that can be synchronized) you can then find the teacher in the other list (it will always be in at least two lists (Teacher.class and BioTeacher.class)) and remove it from that list too.

Then you can make the code so that:

BioTeacher Teacher.getTeacher(BioTeacher.class)

works without additional castings. Again, this is a learning experience and will get you into learning more about Java's generics. (More about this approach at How do I return an instance of an object of the same type as the class passed in using Java 6? )

这篇关于Java中的对象池模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆