我的Java自定义线程池执行器

ThreadPoolExecutor是Java并发api添加的一项功能,可以有效地维护和重用线程,因此我们的程序不必担心创建和销毁线程,而将精力放在核心功能上。 我创建了一个自定义线程池执行程序,以更好地了解线程池执行程序的工作方式。

功能性:

  • 它维护一个固定的线程池,即使没有任务提交也创建线程并启动线程,而ThreadPoolExecutor根据需要创建线程,即,每当将可运行对象提交给池且线程数小于核心池大小时。
  • 在ThreadPoolExecutor中,我们提供了一个等待队列,当所有线程忙于运行现有任务时,新的可运行任务将在该队列中等待。 队列填满后,将创建最大线程池大小的新线程。 在MyThreadPool中,我将可运行对象存储在链接列表中,因此每个任务都将在列表中等待且不受限制,因此在此不使用maxPoolSize。
  • 在ThreadPoolExecutor中,我们使用Future Objects从任务中获取结果,如果结果不可用,则future.get()方法将阻塞,或者使用CompletionService。 在MyThreadPoolExecutor中,我创建了一个名为ResultListener的简单接口,用户必须提供对此的实现,如他希望如何处理输出。 每个任务完成后,ResultListener将获得任务输出的回调,或者在发生任何异常的情况下将调用error方法。
  • 调用shutdown方法时,MyThreadPoolExecutor将停止接受新任务并完成剩余任务。
  • 与ThreadPoolExecutor相比,我提供了非常基本的功能,我使用了简单的线程机制,如wait(),notify(),notifyAll()和join()。
  • 在性能方面,它类似于ThreadPoolExecutor,在某些情况下好一些。 如果您发现任何有趣的结果或改进方法,请告诉我。
package com.util;import java.util.concurrent.Callable;/*** Run submitted task of {@link MyThreadPool} After running the task , It calls* on {@link ResultListener}object with {@link Output}which contains returned* result of {@link Callable}task. Waits if the pool is empty.* * @author abhishek* * @param */import java.util.concurrent.Callable;
/**
* Run submitted task of {@link MyThreadPool} After running the task , It calls
* on {@link ResultListener}object with {@link Output}which contains returned
* result of {@link Callable}task. Waits if the pool is empty.
*
* @author abhishek
*
* @param <V>
*/
public class MyThread<V> extends Thread {/*** MyThreadPool object, from which the task to be run*/private MyThreadPool<V> pool;private boolean active = true;public boolean isActive() {return active;}public void setPool(MyThreadPool<V> p) {pool = p;}/*** Checks if there are any unfinished tasks left. if there are , then runs* the task and call back with output on resultListner Waits if there are no* tasks available to run If shutDown is called on MyThreadPool, all waiting* threads will exit and all running threads will exit after finishing the* task*/public void run() {ResultListener<V> result = pool.getResultListener();Callable<V> task;while (true){task = pool.removeFromQueue();if (task != null){try{V output = task.call();result.finish(output);} catch (Exception e){result.error(e);}} else{if (!isActive())break;else{synchronized (pool.getWaitLock()){try{pool.getWaitLock().wait();} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}}}}}void shutdown() {active = false;}
}
package com.util;
import java.util.LinkedList;
import java.util.concurrent.Callable;
/**
* This class is used to execute submitted {@link Callable} tasks. this class
* creates and manages fixed number of threads User will provide a
* {@link ResultListener}object in order to get the Result of submitted task
*
* @author abhishek
*
*
*/
public class MyThreadPool<V> {private Object waitLock = new Object();public Object getWaitLock() {return waitLock;}/*** list of threads for completing submitted tasks*/private final LinkedList<MyThread<V>> threads;/*** submitted task will be kept in this list untill they run by one of* threads in pool*/private final LinkedList<Callable<V>> tasks;/*** shutDown flag to shut Down service*/private volatile boolean shutDown;/*** ResultListener to get back the result of submitted tasks*/private ResultListener<V> resultListener;/*** initializes the threadPool by starting the threads threads will wait till* tasks are not submitted** @param size* Number of threads to be created and maintained in pool* @param myResultListener* ResultListener to get back result*/public MyThreadPool(int size, ResultListener<V> myResultListener) {tasks = new LinkedList<Callable<V>>();threads = new LinkedList<MyThread<V>>();shutDown = false;resultListener = myResultListener;for (int i = 0; i < size; i++) {MyThread<V> myThread = new MyThread<V>();myThread.setPool(this);threads.add(myThread);myThread.start();}}public ResultListener<V> getResultListener() {return resultListener;}public void setResultListener(ResultListener<V> resultListener) {this.resultListener = resultListener;}public boolean isShutDown() {return shutDown;}public int getThreadPoolSize() {return threads.size();}public synchronized Callable<V> removeFromQueue() {return tasks.poll();}public synchronized void addToTasks(Callable<V> callable) {tasks.add(callable);}/*** submits the task to threadPool. will not accept any new task if shutDown* is called Adds the task to the list and notify any waiting threads** @param callable*/public void submit(Callable<V> callable) {if (!shutDown) {addToTasks(callable);synchronized (this.waitLock) {waitLock.notify();}} else {System.out.println('task is rejected.. Pool shutDown executed');}}/*** Initiates a shutdown in which previously submitted tasks are executed,* but no new tasks will be accepted. Waits if there are unfinished tasks* remaining**/public void stop() {for (MyThread<V> mythread : threads) {mythread.shutdown();}synchronized (this.waitLock) {waitLock.notifyAll();}for (MyThread<V> mythread : threads) {try {mythread.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}
package com.util;/*** This interface imposes finish method * which is used to get the {@link Output} object * of finished task* @author abhishek** @param */public interface ResultListener {public void finish(T obj);public void error(Exception ex);}

您可以根据需要实现此类并返回并处理任务返回的结果。

package com.util;public class DefaultResultListener implements ResultListener{@Overridepublic void finish(Object obj) {}@Overridepublic void error(Exception ex) {ex.printStackTrace();}}

例如,此类将添加task返回的数字。

package com.util;import java.util.concurrent.atomic.AtomicInteger;/*** ResultListener class to keep track of total matched count* @author abhishek* * @param */
public class MatchedCountResultListenerimplements ResultListener{/*** matchedCount to keep track of the number of matches returned by submitted* task*/AtomicInteger matchedCount = new AtomicInteger();/*** this method is called by ThreadPool to give back the result of callable* task. if the task completed successfully then increment the matchedCount by* result count*/@Overridepublic void finish(V obj) {//System.out.println('count is '+obj);matchedCount.addAndGet((Integer)obj);}/*** print exception thrown in running the task*/@Overridepublic void error(Exception ex) {ex.printStackTrace();}/*** returns the final matched count of all the finished tasks* * @return*/public int getFinalCount() {return matchedCount.get();}
}

这是一个测试类,使用CompletionService和MyThreadPoolExecutor对循环运行简单

package test;import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;import com.util.DefaultResultListener;
import com.util.MyThreadPool;public class TestClass {public static void main(String[] args) throws InterruptedException {CompletionServicethreadService;ExecutorService service = Executors.newFixedThreadPool(2);threadService = new ExecutorCompletionService(service);long b = System.currentTimeMillis();for(int i =0;i<50000;i++){threadService.submit(new MyRunable (i));}service.shutdown();System.out.println('time taken by Completion Service ' + (System.currentTimeMillis()-b));DefaultResultListener result = new DefaultResultListener();MyThreadPoolnewPool = new MyThreadPool(2,result);long a = System.currentTimeMillis();int cc =0;for(int i =0;i<50000;i++){cc = cc+i;}System.out.println('time taken without any pool ' + (System.currentTimeMillis()-a));a= System.currentTimeMillis();for(int i =0;i<5000;i++){newPool.submit(new MyRunable (i));}newPool.stop();System.out.println('time taken by myThreadPool ' + (System.currentTimeMillis()-a));}}class MyRunable implements Callable{int index = -1;public MyRunable(int index){this.index = index;}@Overridepublic Integer call() throws Exception {return index;}}

参考: 我的JCG合作伙伴 Abhishek Somani在Java,J2EE和Server博客上的Java 自定义线程池执行程序 。

翻译自: https://www.javacodegeeks.com/2013/03/my-custom-thread-pool-executor-in-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php中mysqlstat函数,PHP函数mysql_stat介绍

&#xfeff;定义和用法mysql_stat() 函数返回 MySQL 服务器的当前系统状态。如果成功&#xff0c;则该函数返回状态。如果失败&#xff0c;则返回 false。语法mysql_stat(connection)提示和注释注释&#xff1a;mysql_stat() 目前只返回 uptime、threads、queries、open table…

全选、全部选、反选、提交

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title> </head> <body><form><input type"checkbox" name"items" value"足球"&…

Java中的模板方法设计模式

模板方法模式是一种行为设计模式&#xff0c;它为算法提供了基础方法&#xff0c;称为模板方法&#xff0c;该方法将其某些步骤推迟到子类中&#xff0c;因此算法结构相同&#xff0c;但某些步骤可以由子类根据上下文重新定义。 模板是指预设格式&#xff0c;例如HTML模板&…

android adb源码分析(1)

ADB是Android debug bridge的缩写&#xff0c;它使用PC机可以通过USB或网络与android设备通讯。 adb的源码位于system/core/adb目录下&#xff0c;先来看下编译脚本Android.mk&#xff1a; [plain] view plaincopy# Copyright 2005 The Android Open Source Project # # Andr…

matlab二次二阶距,用Matlab改进一次二阶矩法程序.doc

用Matlab编的计算结构可靠指标的改进一次二阶矩法程序(验算点法)题目&#xff1a;编制改进一次二阶矩法计算可靠指标的程序&#xff0c;并给出算例&#xff0c;要求提供源程序选取的算例为&#xff1a;zg(x,y)x*y-1140&#xff0c;其中x,y服从正态分布&#xff0c;μx38,Vx0.1,…

winform中的数据绑定

1. 简单的数据绑定 例1 using (SqlConnection conn new SqlConnection(ConfigurationManager.ConnectionStrings["connStr"].ToString())) { SqlDataAdapter sda new SqlDataAdapter("Select * From T_Class Where F_TypeProduct order by F_RootID,F_Order…

jQuery数据表和Java集成

jQuery DataTables是一个开放源代码插件&#xff0c;用于在浏览器中创建表。 它具有许多功能&#xff0c;例如排序&#xff0c;服务器端处理&#xff0c; JQUERY UI主题滚动。 该插件的下载链接&#xff1a; http://www.datatables.net/download/ 在本演示中&#xff0c;我…

CSS 属性 - 伪类和伪元素的区别

伪元素和伪类之所以这么容易混淆&#xff0c;是因为他们的效果类似而且写法相仿&#xff0c;但实际上 css3 为了区分两者&#xff0c;已经明确规定了伪类用一个冒号来表示&#xff0c;而伪元素则用两个冒号来表示。 :Pseudo-classes ::Pseudo-elements 但因为兼容性的问题&…

class-感知机Perception

1 感知机模型1.1 模型定义2 感知机学习策略2.1 数据的线性可分性2.2 学习策略3 学习算法3.1 算法原始形式3.2 收敛性3 学习算法的对偶形式1 感知机模型 感知机perceptron是二类分类问题的线性分类模型&#xff0c;输入为实例的特征向量&#xff0c;输出为实例的类别&#xff08…

图片资源 php,php URL图片资源传参生成对应尺寸图片

最近项目中需要上传大图&#xff0c;然后不同设备请求不同大小的图片&#xff0c;之前有用过一个通过URL参数来获取不同大小的图片的接口感觉设计方式请不错&#xff0c;于是就百度看看类似是如何实现的&#xff0c;找了几天找个两个功能类似的记录下。1、图片服务器 imagemagi…

Java中的方法调用有多昂贵

我们都去过那儿。 在查看设计不良的代码的同时&#xff0c;听听作者对人们永远不应该牺牲性能而不是设计的解释。 而且&#xff0c;您不能说服作者摆脱其500行方法&#xff0c;因为链接方法调用会破坏性能。 好吧&#xff0c;这可能在1996年左右是正确的。 但是自那时以来&…

UVa-116 Unidirectional TSP 单向旅行商

题目 https://vjudge.net/problem/uva-116 分析 设d[i][j]为从(i,j)到最后一列的最小开销&#xff0c;则d[i][j]a[i][j]max(d[i1][j1],d[i-1][j1]) 参考数字三角形,用逆推的方法,先确定最后一列d[i][n-1]a[i][n-1],再确定n-2列,此时d[i][n-2] a[i][n-2]min(d[i][n-1],d[i-1][n…

1.HTML

HTML简介 hyper text markup language 即超文本标记语言。 超文本: 就是指页面内可以包含图片、链接&#xff0c;甚至音乐、程序等非文字元素。 标准模板 <!DOCTYPE html> <html lang"en"><head> <meta charset"U…

error connection reset by peer 104

connection reset by peer的常见原因 1.服务器的并发连接数超过了其承载量&#xff0c;服务器会将其中一些连接关闭&#xff1b;2. errno 104错误表明你在对一个对端socket已经关闭的的连接调用write或send方法&#xff0c;在这种情况下&#xff0c;调用write或send方法后&…

php记住表单数据cookie,【PHP基础】cookies和session

1.Cookiescookie 常用于识别用户。cookie 是服务器留在用户计算机中的小文件。每当相同的计算机通过浏览器请求页面时&#xff0c;它同时会发送 cookie。通过 PHP&#xff0c;您能够创建并取回 cookie 的值。1.1、如何创建 cookie&#xff1f;setcookie() 函数用于设置 cookie。…

自己构建GlassFish 4.0快照

这篇文章是关于自己发布GlassFish 4.0快照的&#xff0c;其中包括一些黑客。 我找到了GlassFish FullBuild的官方说明&#xff0c;然后决定自己构建服务器。 有时&#xff0c;您可能不想等待团队升级GlassFish构建文件。 在本条目中&#xff0c;我将Artifactory称为私有Maven存…

【转】utf-8的中文是一个汉字占三个字节长度

因为看到百度里面这个人回答比较生动&#xff0c;印象比较深刻&#xff0c;所以转过来做个笔记 原文链接 https://zhidao.baidu.com/question/1047887004693001899.html 知乎也有更清晰解答 https://www.zhihu.com/question/23374078 1、美国人首先对其英文字符进行了编码&am…

matlab升压斩波仿真,升压斩波电路设计与仿真.doc

升压斩波电路设计与仿真1.序言近年来&#xff0c;不断进步的计算机技术为现代控制技术在实际生产、生活中提供了强有力的技术支持&#xff0c;新的材料和结构器件又促进了电力电子技术的飞速发展&#xff0c;且在各行业中得到广泛的应用。电力电子技术(Power Electronics Techn…

Python selenium web UI之Chrome 与 Chromedriver对应版本映射表及下载地址和配置(windows, Mac OS)...

浏览器及驱动下载 进行web UI 自动化时&#xff0c;需要安装浏览器驱动webdriver&#xff0c;Chrome浏览器需要安装chromedriver.exe 驱动&#xff0c;Firefox需安装 geckodriver.exe 驱动。 Chrome 下载&#xff1a; http://www.slimjet.com/chrome/google-chrome-old-version…

先进的ListenableFuture功能

上次我们熟悉了ListenableFuture 。 我答应介绍更高级的技术&#xff0c;即转换和链接。 让我们从简单的事情开始。 假设我们有从某些异步服务获得的ListenableFuture<String> 。 我们还有一个简单的方法&#xff1a; Document parse(String xml) {//...我们不需要Strin…