js 实现轻量ps_简单轻量的池实现
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中獲得 。
翻譯自: https://www.javacodegeeks.com/2013/08/simple-and-lightweight-pool-implementation.html
js 實現輕量ps
總結
以上是生活随笔為你收集整理的js 实现轻量ps_简单轻量的池实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 镀铬怎么读 镀铬解释
- 下一篇: 雪人英语怎么读 雪人词语的英文