js 实现轻量ps

对象池是包含指定数量的对象的容器。 从池中获取对象时,在将对象放回之前,该对象在池中不可用。 池中的对象具有生命周期:创建,验证,销毁等。池有助于更好地管理可用资源。 有许多使用示例。 特别是在应用程序服务器中,有数据源池,线程池等。在以下情况下应使用池:

  • 高频使用相同的物体
  • 对象很大,消耗很多内存
  • 对象需要很多时间进行初始化
  • 对象使用大量的IO操作(流,套接字,数据库等)
  • 对象不是线程安全的

当我为我的一个Java项目寻找一个池实现时,我发现许多人都引用了Apache Commons Pool 。 Apache Commons Pool提供了一个对象池API。 有接口ObjectPool,ObjectPoolFactory,PoolableObjectFactory和许多实现。 池提供方法addObject,借款对象,invalidateObject,returnObject来添加,获取,移除和返回对象。 PoolableObjectFactory定义池中对象的行为,并为池的操作提供各种回调。

在仔细研究实现细节之后,我发现Apache Commons Pool不是轻量级的实现,这对我来说是一个开销。 此外,它对许多方法都使用了旧的Java关键字sync,因此不建议使用许多方法。 Java 5引入了用于Java并发(多线程)的Executor框架。 此处最好使用Executor框架。 我决定实现一个简单且轻量级的池,我想在这里介绍它。 它只是一个Java类。 我认为如果您不需要回调和其他高级功能就足够了。 我在GitHub上创建了一个项目easy-pool 。

池实现基于java.util.concurrent包中的ConcurrentLinkedQueue。 ConcurrentLinkedQueue是基于链接节点的线程安全队列。 该队列按照FIFO原理(先进先出)对元素进行排序。 我对通用池的实现如下所示

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public abstract class ObjectPool<T>
{private ConcurrentLinkedQueue<T> pool;private ScheduledExecutorService executorService;/*** Creates the pool.** @param minIdle minimum number of objects residing in the pool*/public ObjectPool(final int minIdle) {// initialize poolinitialize(minIdle);}/*** Creates the pool.** @param minIdle            minimum number of objects residing in the pool* @param maxIdle            maximum number of objects residing in the pool* @param validationInterval time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread.*                           When the number of objects is less than minIdle, missing instances will be created.*                           When the number of objects is greater than maxIdle, too many instances will be removed.*/public ObjectPool(final int minIdle, final int maxIdle, final long validationInterval) {// initialize poolinitialize(minIdle);// check pool conditions in a separate threadexecutorService = Executors.newSingleThreadScheduledExecutor();executorService.scheduleWithFixedDelay(new Runnable(){@Overridepublic void run() {int size = pool.size();if (size < minIdle) {int sizeToBeAdded = minIdle - size;for (int i = 0; i < sizeToBeAdded; i++) {pool.add(createObject());}} else if (size > maxIdle) {int sizeToBeRemoved = size - maxIdle;for (int i = 0; i < sizeToBeRemoved; i++) {pool.poll();}}}}, validationInterval, validationInterval, TimeUnit.SECONDS);}/*** Gets the next free object from the pool. If the pool doesn't contain any objects,* a new object will be created and given to the caller of this method back.** @return T borrowed object*/public T borrowObject() {T object;if ((object = pool.poll()) == null) {object = createObject();}return object;}/*** Returns object back to the pool.** @param object object to be returned*/public void returnObject(T object) {if (object == null) {return;}this.pool.offer(object);}/*** Shutdown this pool.*/public void shutdown() {if (executorService != null) {executorService.shutdown();}}/*** Creates a new object.** @return T new object*/protected abstract T createObject();private void initialize(final int minIdle) {pool = new ConcurrentLinkedQueue<T>();for (int i = 0; i < minIdle; i++) {pool.add(createObject());}}
}

抽象类ObjectPool提供了两个主要方法:roweObject从池中获取下一个空闲对象,returnObject将借入的对象返回池中。 如果池中不包含任何对象,则将创建一个新对象,并将其交还给借阅方法的调用者。 对象创建在方法createObject中进行。 任何扩展抽象类ObjectPool的类都只需实现此方法,即可使用该池。 如您所见,我还利用java.util.concurrent包中的ScheduledExecutorService。 这有什么用? 您可以指定池中驻留的最小和最大对象数。 ScheduledExecutorService在单独的线程中启动特殊任务,并在指定时间(参数validationInterval)中观察定期对象池中的最小和最大数量。 当对象数小于最小值时,将创建丢失的实例。 当对象数大于最大值时,将删除太多实例。 有时这对于平衡池中的内存消耗对象以及更多对象很有用。

让我们实现测试类以显示对具体池的使用。 首先,我们需要一个表示池中对象的类,该类模拟耗时的过程。 称为ExportingProcess的此类需要一些时间才能实例化。

public class ExportingProcess {private String location;private long processNo = 0;public ExportingProcess(String location, long processNo) {this.location = location;this.processNo = processNo;// doing some time expensive calls / tasks// ...// for-loop is just for simulationfor (int i = 0; i < Integer.MAX_VALUE; i++) {}System.out.println("Object with process no. " + processNo + " was created");}public String getLocation() {return location;}public long getProcessNo() {return processNo;}
}

第二类实现Runnable接口并模拟线程执行的某些任务。 在run方法中,我们借用了ExportingProcess的一个实例,稍后将其返回到池中。

public class ExportingTask implements Runnable {private ObjectPool<ExportingProcess> pool;private int threadNo;public ExportingTask(ObjectPool<ExportingProcess> pool, int threadNo) {this.pool = pool;this.threadNo = threadNo;}public void run() {// get an object from the poolExportingProcess exportingProcess = pool.borrowObject();System.out.println("Thread " + threadNo + ": Object with process no. " + exportingProcess.getProcessNo() + " was borrowed");// do something// ...// for-loop is just for simulationfor (int i = 0; i < 100000; i++) {}// return ExportingProcess instance back to the poolpool.returnObject(exportingProcess);System.out.println("Thread " + threadNo + ": Object with process no. " + exportingProcess.getProcessNo() + " was returned");}
}

现在,在JUnit类TestObjectPool中,我们创建一个ExportingProcess类型的对象池。 这是通过新的ObjectPool <ExportingProcess>(4,10,5)发生的。 参数在下面的注释中描述。

import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;public class TestObjectPool
{private ObjectPool<ExportingProcess> pool;private AtomicLong processNo = new AtomicLong(0);@Beforepublic void setUp() {// Create a pool of objects of type ExportingProcess. Parameters:// 1) Minimum number of special ExportingProcess instances residing in the pool = 4// 2) Maximum number of special ExportingProcess instances residing in the pool = 10// 3) Time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread = 5.//    When the number of ExportingProcess instances is less than minIdle, missing instances will be created.//    When the number of ExportingProcess instances is greater than maxIdle, too many instances will be removed.//    If the validation interval is negative, no periodical checking of minIdle / maxIdle conditions//    in a separate thread take place. These boundaries are ignored then.pool = new ObjectPool<ExportingProcess>(4, 10, 5){protected ExportingProcess createObject() {// create a test object which takes some time for creationreturn new ExportingProcess("/home/temp/", processNo.incrementAndGet());}};}@Afterpublic void tearDown() {pool.shutdown();}@Testpublic void testObjectPool() {ExecutorService executor = Executors.newFixedThreadPool(8);// execute 8 tasks in separate threadsexecutor.execute(new ExportingTask(pool, 1));executor.execute(new ExportingTask(pool, 2));executor.execute(new ExportingTask(pool, 3));executor.execute(new ExportingTask(pool, 4));executor.execute(new ExportingTask(pool, 5));executor.execute(new ExportingTask(pool, 6));executor.execute(new ExportingTask(pool, 7));executor.execute(new ExportingTask(pool, 8));executor.shutdown();try {executor.awaitTermination(30, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();}}
}

测试输出看起来像

Object with process no. 1 was created
Object with process no. 2 was created
Object with process no. 3 was created
Object with process no. 4 was created
Thread 2: Object with process no. 2 was borrowed
Thread 1: Object with process no. 1 was borrowed
Thread 2: Object with process no. 2 was returned
Thread 3: Object with process no. 3 was borrowed
Thread 4: Object with process no. 4 was borrowed
Thread 1: Object with process no. 1 was returned
Thread 4: Object with process no. 4 was returned
Thread 8: Object with process no. 4 was borrowed
Thread 5: Object with process no. 1 was borrowed
Thread 7: Object with process no. 3 was borrowed
Thread 3: Object with process no. 3 was returned
Thread 6: Object with process no. 2 was borrowed
Thread 7: Object with process no. 3 was returned
Thread 5: Object with process no. 1 was returned
Thread 8: Object with process no. 4 was returned
Thread 6: Object with process no. 2 was returned

可以看出,访问该池的第一个线程创建了驻留在池中的最少对象。 多次运行该测试类,我们会发现有时4个对象相互借用,并且会在池中创建一个新的5.对象。 所有测试类均可在GitHub中获得 。

参考:来自JCG合作伙伴 Oleg Varaksin的简单轻量级池实现 ,位于“ 软件开发思想”博客上。

翻译自: https://www.javacodegeeks.com/2013/08/simple-and-lightweight-pool-implementation.html

js 实现轻量ps

js 实现轻量ps_简单轻量的池实现相关推荐

  1. 腾讯云轻量数据库服务简单测评

    0x00 前言 腾讯云的轻量数据库服务最近开放公测了.各位建站肯定是离不开高性能的数据库的,今天来简单对腾讯云轻量数据库服务简单测评一下. 0x01 价格及配置信息 轻量数据库服务和轻量应用服务器一样 ...

  2. 轻量、简单、易容、免费的bug管理工具-delbug管理

    轻量.简单.易容.免费的bug管理工具-delbug管理 在整个软件开发周期中测试的重要性不言而喻,它直接决定了软件的健壮性和可用性.在如今新软件层出不穷,软件迭代不断加快的时代.完善的测试更是显得弥 ...

  3. 刷题H5应用网站源码-无后端无数据库轻量化部署简单

    介绍: 特色内容: 无后端.无数据库轻量化部署简单 使用JSON作为题库存储,层次清晰,结构简单易懂 有配套的word模板和模板到JSON转换工具 四种题模式:顺序题.乱序题.错题模式.背题模式 主要 ...

  4. 【JS基础】基本格式、字面量和变量、标志符、字符串

    基本格式 //单行注释 /* */多行注释 利用注释进行简单的调试 严格区分大小写. 每一条语句以分号结尾.如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,甚至有些时候浏览器会加错分号. 会忽 ...

  5. php字面量,浅谈js之字面量、对象字面量的访问、关键字in的用法

    一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal) ...

  6. 统计单词数,题解简单易懂量少

    题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ...

  7. Pico.css大道至简返璞归真--一个简单轻量化的CSS框架

    Pico.css是什么? Pico.css是一个简单轻量化的CSS UI框架,最大的特点是样式都基于HTML原始的标签名和内置的属性,少用甚至是不用class来定义样式,写出来的代码语义清晰,可维护性 ...

  8. js之字面量、对象字面量的访问、关键字in的用法

    一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal) ...

  9. 数据表示字面量整型字面量

    数据表示字面量整型字面量 编写程序,首先面对的是数据.在程序中,数据该如何表示出来?根据表示的方式不同,数据通常有两种表示方式:直观表示和指代表示.本章将详细讲解这两种表示方式本文选自明明白白学C#大 ...

最新文章

  1. ubuntu ssh 客户端查看服务器端图形界面
  2. Sequential 顺序模型和 Model 模型【TensorFlow2入门手册】
  3. python爬取百度贴吧xpath_爬虫基础系列xpath实战——爬取百度贴吧图片(3)
  4. JAVA获取图片的宽、高和大小
  5. Swagger学习和实践
  6. vue 兼容IE报错解决方案
  7. NEAT(NeuroEvolution of Augmenting Topologies)算法详解与实践(基于NEAT-Python)
  8. 数据链路层的介质访问控制协议
  9. office2003 office2007同时安装 配置问题的解决
  10. 如何在 MacBook Pro 上调整显示设置?
  11. 随笔记----关于python 和C++ 里面的与或问题
  12. Java如何将窗口居中显示
  13. 如何判断对方列表里是不是好友_QQ怎么知道自己是不是对方好友
  14. 将Excel表格中的数字文本格式转化为数字格式
  15. ★40个经典的社交心理学现象
  16. HTML篇三——(1)
  17. 马上金三银四了,注意下面这几点,面试通过率高达85%
  18. Vue2源码解析 虚拟dom简介
  19. command a expects \ followed by text
  20. 利用Web查询文件(.iqy)有效钓鱼

热门文章

  1. GYM 101908F - Music Festival
  2. Wannafly挑战赛17
  3. codeforces 935E Fafa and Ancient Mathematics 语法树、动态规划
  4. 北方大学 ACM 多校训练赛 第十五场 蜘蛛牌A
  5. 稍微有点难度的10道java面试题,你会几道?
  6. sql server简单查询
  7. 用python画出吉祥物
  8. shiro-权限概述
  9. 转: 虚拟IP(VIP)原理
  10. java 创建uri_使用UriBuilder快速创建URI