1)类结构
.
|____BaseTask.java 任务抽象类,具体的任务都要继承它
|____TaskHandlerContext.java 单例的任务执行类
|____Fabi.java 斐波那契计算工具类
|____FabiTask.java 一个具体的任务: 执行斐波那契
|____Main.java 主类,模拟收到的任务
2)思路
把收到的数据都封装为一个Task,然后自增任务id,不断的去添加任务到线程的任务队列,然后任务被消耗不断执行即可。
任务队列是一个阻塞队列,一个任务执行完毕,就线程自动取出下一个任务,继续执行。
3)具体实现
|____BaseTask.java
package taskdispatcher;
public abstract class BaseTask implements Runnable {
private int id;
public BaseTask(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
|____TaskHandlerContext.java
package taskdispatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class TaskHandlerContext {
private TaskHandlerContext() {
this.init();
}
// 单例类
public static TaskHandlerContext INSTANCE = new TaskHandlerContext();
private final int CORE_SIZE = Runtime.getRuntime().availableProcessors();
private final List workerPool = new ArrayList<>();
private ExecutorService executorService = Executors.newFixedThreadPool(CORE_SIZE);
private void init() {
for (int i = 0; i < CORE_SIZE; i++) {
TaskWorker worker = new TaskWorker(i);
workerPool.add(worker);
// 把任务线程放到线程池中
executorService.execute(worker);
}
}
public void acceptTask(BaseTask task) {
int key = task.getId() % workerPool.size();
TaskWorker taskWorker = workerPool.get(key);
taskWorker.addTask(task);
System.out.println("任务:" + task.getId() + " 已经提交给线程" + taskWorker.id);
}
private class TaskWorker implements Runnable {
private int id;
private BlockingQueue taskQueue = new LinkedBlockingQueue<>();
public TaskWorker(int id) {
this.id = id;
}
@Override
public void run() {
while (true) {
try {
Runnable runnable = taskQueue.take();
System.out.printf("%s 取出任务,开始执行\n", "线程" + id);
runnable.run();
} catch (InterruptedException e) {
System.out.printf("%s 执行异常 %s", "线程" + id, e);
}
}
}
public void addTask(BaseTask task) {
this.taskQueue.add(task);
}
}
}
|____Fabi.java
package taskdispatcher;
public class Fabi {
public static int f(int n) {
if (n <= 2) {
return 1;
}
return f(n - 2) + f(n - 2);
}
}
|____FabiTask.java
package taskdispatcher;
import java.util.concurrent.atomic.AtomicInteger;
public class FabiTask extends BaseTask {
private static AtomicInteger num = new AtomicInteger(0);
private int n;
public FabiTask(int n) {
super(num.getAndIncrement() % 10000);
this.n = n;
}
@Override
public void run() {
int r = Fabi.f(n);
System.out.println("任务编号:" + this.getId() + "执行结束,获得结果:" + r);
}
}
|____Main.java
package taskdispatcher;
public class Main {
public static void main(String[] args) {
// 模拟收到的客户端的信息,被封装成任务,不断执行
while (true) {
try {
TaskHandlerContext.INSTANCE.acceptTask(new FabiTask(60));
Thread.sleep(Math.abs(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/*
线程0 取出任务,开始执行
任务:0 已经提交给线程0
线程1 取出任务,开始执行
任务:1 已经提交给线程1
任务:2 已经提交给线程2
线程2 取出任务,开始执行
任务:3 已经提交给线程3
线程3 取出任务,开始执行
任务:4 已经提交给线程0
任务:5 已经提交给线程1
任务:6 已经提交给线程2
任务:7 已经提交给线程3
任务:8 已经提交给线程0
任务:9 已经提交给线程1
任务:10 已经提交给线程2
任务:11 已经提交给线程3
任务:12 已经提交给线程0
任务:13 已经提交给线程1
任务:14 已经提交给线程2
任务:15 已经提交给线程3
任务:16 已经提交给线程0
任务:17 已经提交给线程1
任务:18 已经提交给线程2
任务:19 已经提交给线程3
任务:20 已经提交给线程0
任务:21 已经提交给线程1
任务编号:1执行结束,获得结果:536870912
线程1 取出任务,开始执行
任务:22 已经提交给线程2
任务编号:2执行结束,获得结果:536870912
线程2 取出任务,开始执行
任务:23 已经提交给线程3
任务编号:3执行结束,获得结果:536870912
线程3 取出任务,开始执行
任务:24 已经提交给线程0
任务:25 已经提交给线程1
任务:26 已经提交给线程2
任务:27 已经提交给线程3
任务编号:0执行结束,获得结果:536870912
线程0 取出任务,开始执行
任务:28 已经提交给线程0
任务:29 已经提交给线程1
任务:30 已经提交给线程2
任务:31 已经提交给线程3
任务:32 已经提交给线程0
任务:33 已经提交给线程1
任务:34 已经提交给线程2
任务:35 已经提交给线程3
任务:36 已经提交给线程0
任务:37 已经提交给线程1
任务编号:5执行结束,获得结果:536870912
线程1 取出任务,开始执行
任务:38 已经提交给线程2
任务编号:6执行结束,获得结果:536870912
线程2 取出任务,开始执行
任务编号:7执行结束,获得结果:536870912
线程3 取出任务,开始执行
任务:39 已经提交给线程3
任务:40 已经提交给线程0
任务:41 已经提交给线程1
*/