Java并发对象池?
我尝试将外部非线程安全库集成到我的web项目中;我发现为每个客户端线程创建这个对象的实例太昂贵了 因此,我想创建一个具有以下属性的对象池Java并发对象池?,java,concurrency,thread-safety,threadpool,java.util.concurrent,Java,Concurrency,Thread Safety,Threadpool,Java.util.concurrent,我尝试将外部非线程安全库集成到我的web项目中;我发现为每个客户端线程创建这个对象的实例太昂贵了 因此,我想创建一个具有以下属性的对象池 动态对象创建,池中的对象将动态创建,而不是在构造函数中创建。池最初是空的,当客户端线程获取资源对象时,池可以根据需要创建新资源。一旦创建对象的数量达到池的大小;然后新的客户端线程将被阻塞,并等待其他线程回收资源 池应该是公平的,公平性确保第一个请求的线程是第一个获取的线程;否则,一些线程可能会永远等待 我怎么做?如果有工作示例,我将不胜感激。此问题和解决方案总
我怎么做?如果有工作示例,我将不胜感激。此问题和解决方案总结自 Java并发包中的阻塞队列可以构建并发对象池,ArrayBlockingQueue也支持我们所要求的公平性。在这个实现中,我使用ReentrantLock控制是否可以在池中创建新对象。因此,在非动态创建模式下,即在构造函数中创建所有对象时,此锁将始终被锁定;在动态创建模式下,每次只能创建一个对象,因此如果有另一个线程获取此对象,它将从阻止删除的pool.take()中获取该对象,并等待队列中的新可用资源
public abstract class ResourcePool {
private final BlockingQueue pool;
private final ReentrantLock lock = new ReentrantLock();
private int createdObjects = 0;
private int size;
protected ResourcePool(int size) {
this(size, false);
}
protected ResourcePool(int size, Boolean dynamicCreation) {
// Enable the fairness; otherwise, some threads
// may wait forever.
pool = new ArrayBlockingQueue<>(size, true);
this.size = size;
if (!dynamicCreation) {
lock.lock();
}
}
public Resource acquire() throws Exception {
if (!lock.isLocked()) {
if (lock.tryLock()) {
try {
++createdObjects;
return createObject();
} finally {
if (createdObjects < size) lock.unlock();
}
}
}
return pool.take();
}
public void recycle(Resource resource) throws Exception {
// Will throws Exception when the queue is full,
// but it should never happen.
pool.add(resource);
}
public void createPool() {
if (lock.isLocked()) {
for (int i = 0; i < size; ++i) {
pool.add(createObject());
createdObjects++;
}
}
}
protected abstract Resource createObject();
}
公共抽象类资源池{
私有最终阻塞队列池;
private final ReentrantLock lock=new ReentrantLock();
私有int createdObjects=0;
私有整数大小;
受保护的资源池(整数大小){
这个(大小,错误);
}
受保护的资源池(整数大小,布尔动态创建){
//启用公平性;否则,某些线程
//可能永远等待。
池=新的ArrayBlockingQueue(大小,true);
这个。大小=大小;
如果(!dynamicCreation){
lock.lock();
}
}
公共资源acquire()引发异常{
如果(!lock.isLocked()){
if(lock.tryLock()){
试一试{
++createdObjects;
返回createObject();
}最后{
if(createdObjects
在下面的示例中,有5个客户端线程同时获取资源池中的两个DataTimeFormat对象,这些客户端线程总共将进行30次计算
class DataTimeFormatResourcePool extends ResourcePool<SimpleDateFormat> {
DataTimeFormatResourcePool(int size, Boolean dynamicCreation) {
super(size, dynamicCreation);
createPool();
}
@Override
protected SimpleDateFormat createObject() {
return new SimpleDateFormat("yyyyMMdd");
}
public Date convert(String input) throws Exception {
SimpleDateFormat format = acquire();
try {
return format.parse(input);
} finally {
recycle(format);
}
}
}
public class ResourcePoolExample {
public static void main(String args[]) {
final DataTimeFormatResourcePool pool = new DataTimeFormatResourcePool(2, true);
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return pool.convert("20130224");
}
};
ExecutorService exec = Executors.newFixedThreadPool(5);
List<Future<Date>> results = new ArrayList<>();
for (int i = 0; i < 30; i++) {
results.add(exec.submit(task));
}
exec.shutdown();
try {
for (Future<Date> result : results) {
System.out.println(result.get());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
class DataTimeFormatResourcePool扩展了ResourcePool{
DataTimeFormatResourcePool(整数大小,布尔动态创建){
超级(大小、动态创建);
createPool();
}
@覆盖
受保护的SimpleDataFormat createObject(){
返回新的SimpleDataFormat(“yyyyMMdd”);
}
公共日期转换(字符串输入)引发异常{
SimpleDataFormat格式=获取();
试一试{
返回format.parse(输入);
}最后{
回收(格式);
}
}
}
公共类资源池示例{
公共静态void main(字符串参数[]){
最终DataTimeFormatResourcePool池=新DataTimeFormatResourcePool(2,true);
可调用任务=新的可调用任务(){
@覆盖
公共日期调用()引发异常{
返回池。转换(“20130224”);
}
};
ExecutorService exec=Executors.newFixedThreadPool(5);
列表结果=新建ArrayList();
对于(int i=0;i<30;i++){
结果.添加(执行.提交(任务));
}
exec.shutdown();
试一试{
用于(未来结果:结果){
System.out.println(result.get());
}
}catch(异常示例){
例如printStackTrace();
}
}
}
链接现在不可用