Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java并发对象池?_Java_Concurrency_Thread Safety_Threadpool_Java.util.concurrent - Fatal编程技术网

Java并发对象池?

Java并发对象池?,java,concurrency,thread-safety,threadpool,java.util.concurrent,Java,Concurrency,Thread Safety,Threadpool,Java.util.concurrent,我尝试将外部非线程安全库集成到我的web项目中;我发现为每个客户端线程创建这个对象的实例太昂贵了 因此,我想创建一个具有以下属性的对象池 动态对象创建,池中的对象将动态创建,而不是在构造函数中创建。池最初是空的,当客户端线程获取资源对象时,池可以根据需要创建新资源。一旦创建对象的数量达到池的大小;然后新的客户端线程将被阻塞,并等待其他线程回收资源 池应该是公平的,公平性确保第一个请求的线程是第一个获取的线程;否则,一些线程可能会永远等待 我怎么做?如果有工作示例,我将不胜感激。此问题和解决方案总

我尝试将外部非线程安全库集成到我的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();
            }
        }
    }
    
    链接现在不可用