一个与业务无关的java多线程实现方法
来源:互联网 发布:民王 知乎 编辑:程序博客网 时间:2024/05/16 01:50
前不久项目中做到接口同步数据,由于数据量比较大,所以考虑到了多线程,根据java设计思想,尽量解开耦合和模块化,所以这次设计出来一个线程组,将线程和业务分离,这正符合java设计思想中的松耦合。今天给大家分享一下。
这套多线程代码中一共有3个类构成,分别是以下三个
task.java 该类为一个抽象类,定义了一个方法,该类没有具体业务逻辑,作为一个多线程的抽象父类,待其他具体业务实现去继承,因为我多线程中要执行某个类的某个方法,肯定不能凭空去执行,所以搞一个父类,这样不管你执行什么任务,只要你继承我的这个task,业务实现写在我要执行的这个execut这个方法中,这样就实现了多线程和业务的无关性。
WorkThread 该类是继承于java的多线程Thread类,他主要负责将任务list类进行循环启动执行,这样就可以实现一个多线程类可以执行多个任务,该类中包含一个成员变量就是task的集合,当该类的run方法执行时就会将它本身的list 中的task任务循环进行执行。
TaskHandOut 该类是这个组合中的业务逻辑处理部分,它负责将线程平均分派,将任务平均分派到各个线程中。
具体见以下代码
1 task.java
import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * @author Thinkpad * * 上午10:52:04 */public abstract class Task {public static final Log logger = LogFactory.getLog(Task.class);/** * 实现需要执行的任务 */public abstract void execute() throws Exception;public void execute_t() throws Exception {long starttime = System.currentTimeMillis();execute();long endtime = System.currentTimeMillis();long time = endtime - starttime;logger.info("执行单个任务消耗时间为:" + time + "ms.");}}
2WorkThread
import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * @author Thinkpad * * 上午10:53:20 */public class WorkThread extends Thread {public static final Log logger = LogFactory.getLog(WorkThread.class);// 本线程待执行的任务列表private List<Task> taskList = null;/** * 构造工作线程,为其指派任务列表 * * @param taskList * 执行的任务列表 */public WorkThread(List<Task> taskList) {this.taskList = taskList;}/** * 执行被指派的所有任务 */public void run() {logger.info("线程开始执行......");long starttime = System.currentTimeMillis();for (Task task : taskList) {try {task.execute_t();} catch (Exception e) {logger.error("执行任务出错!",e);}}long endtime = System.currentTimeMillis();long time = endtime - starttime;logger.info("当前线程" + this.currentThread().getId() +"执行消耗时间为:" + time + "ms.");}}
3TaskHandOut
public class TaskHandOut {public static final Log logger = LogFactory.getLog(TaskHandOut.class);//工作线程数private int threadCount;public TaskHandOut() {//默认启动线程数为5this.threadCount = 10;}/** * 指定启动线程数 * @param threadCount 1<theadCount<20 */public TaskHandOut(int tCount) throws Exception{if(tCount <1 || tCount >20)throw new Exception("启动线程数设置不合法![1-20]之间");this.threadCount = tCount;}/** * 将任务列表分发到工作线程中执行 * @param taskList 任务列表 */@SuppressWarnings("unchecked")public void threadLaunch(List<Task> taskList) {List[] taskListPerThread = handOutTasks(taskList, this.threadCount);System.out.println("实际要启动的工作线程数:" + taskListPerThread.length);logger.debug("实际启动的线程数:" + taskListPerThread.length);for (int i = 0; i < taskListPerThread.length; i++) {Thread workThread = new WorkThread(taskListPerThread[i]);workThread.start();}}/** * 把 List 中的任务分配给每个线程 * * @param taskList * 待分派的任务列表 * @param threadCount * 线程数 * @return */@SuppressWarnings("unchecked")private static List[] handOutTasks(List<Task> taskList, int threadCount) {logger.info("要执行的任务数为:" + taskList.size());// 每个线程至少要执行的任务数int minTaskCount = taskList.size() / threadCount;// 平均分配后还剩下的任务数int remainTaskCount = taskList.size() % threadCount;// 实际要启动的线程数int actualThreadCount = minTaskCount > 0 ? threadCount: remainTaskCount;List<Task>[] taskListPerThread = new List[actualThreadCount];int taskIndex = 0;int remainIndces = remainTaskCount;for (int i = 0; i < taskListPerThread.length; i++) {taskListPerThread[i] = new ArrayList();// 如果大于零,线程要分配到基本的任务if (minTaskCount > 0) {for (int j = taskIndex; j < minTaskCount + taskIndex; j++) {taskListPerThread[i].add(taskList.get(j));}taskIndex += minTaskCount;}// 填补剩余的任务if (remainIndces > 0) {taskListPerThread[i].add(taskList.get(taskIndex++));remainIndces--;}}return taskListPerThread;}public static void main(String[] args) throws Exception {List<Task> taskList = new ArrayList();for (int i = 0; i < 100; i++) {taskList.add(new TaskItem());}TaskHandOut tt = new TaskHandOut(15);tt.threadLaunch(taskList);}}class TaskItem extends Task {/* (non-Javadoc) * @see com.p95169.hrs.thread.Task#execute() */@Overridepublic void execute() throws Exception {System.out.println("开始执行任务!");}}
具体使用如下
你需要将你的具体业务实现类继承于task类,并将具体方法写入到exeute方法中,或者你多写一个类,将你的业务类注入进来,在另外你单独写的类上exeute调用你的业务方法。这样要看你具体需求。以下贴出来我自己的用法
List<Task> taskLst=new ArrayList<Task>();
ApplicationContext ctx =SpringContextHolder.getApplicationContext();
for (int i = 0; i < li.size();i++) {
HospitalVO hi = li.get(i);
deptMgrSynThread=(DeptSynThread) ctx.getBean("bjDeptMgrSynThread");
deptMgrSynThread.setHi(hi);
taskLst.add(deptMgrSynThread);
}
taskHandOut.threadLaunch(taskLst);
deptMgrSynThread就是我单独写的实现task的实现类,为了将我的业务类注入进来。
以上对象taskHandOut 的获得我是靠spring注入的,当然大家也可以直接new获得,根据你具体应用而变。- 一个与业务无关的java多线程实现方法
- Java多线程执行业务方法
- Java多线程同步(锁)的实现方法(synchronised 与reentrantlock)
- java多线程的实现方法
- java多线程的实现方法
- Java实现多线程的方法
- Java实现多线程的方法
- Java多线程的实现方法
- JAVA实现多线程的方法
- Java的多线程实现方法
- java实现多线程的方法
- java【多线程】两个实现多线程的方法
- 用matlab实现一个简单的离群点挖掘(与时序无关)
- 为什么数据表中都要添加一个业务无关的ID字段
- java多线程调用 单例类中一个的方法
- Java 基础-- 实现java多线程的方法
- 存储过程实现业务与java分层实现业务比较
- 无特殊需求下Innodb建议使用与业务无关的自增ID作为主键
- Barty的表格
- Js中sort()方法的用法
- 软件编码人员应具备的空间观
- 让你的C++代码变的更加强大
- 蛋疼研究之怎样刷屏最快?
- 一个与业务无关的java多线程实现方法
- [创建型模式:抽象工厂模式]
- jsp
- nLogn LCS 算法总结
- 变焦与对焦
- 静态查找
- log4j详解与实战
- 这样的递归,我实在无语
- secureCRT连接linux虚拟机