项目中在计算权限的时候有性能有问题,简单的使用多线程的方式改造了下,在这个地方记录一下,防止遗忘。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.commons.lang.StringUtils;
import com.xxx.zzz.account.model.Account;
import com.xxx.zzz.common.ServiceBeanFactory;
import com.xxx.zzz.common.exception.ZZZRuntimeException;
import com.xxx.zzz.common.log.LoggerHelper;
import com.xxx.zzz.resource.model.Resource;
public class ConcurrentAccountTreeCalculator {
private final static int MAX_THREAD = 20;
private final static int TASK_PER_THREAD = 5;
private static ExecutorService initExecutor(int taskNum){
int threadNum = 0;
if(taskNum / TASK_PER_THREAD > MAX_THREAD){
threadNum = MAX_THREAD;
} else {
threadNum = (taskNum / TASK_PER_THREAD) + 1;
}
return Executors.newFixedThreadPool(threadNum);
}
public static Set<String> calculate(List<String> userNames,Resource resource){
List<Future<String>> futures = new ArrayList<Future<String>>();
Set<String> destNames = new HashSet<String>(userNames);
int taskSize = userNames.size();
ExecutorService exec = initExecutor(taskSize);
List<Callable<String>> tasks = new ArrayList<Callable<String>>(taskSize);
for(String userName : userNames){
AccountTreeCalculator calculator = new AccountTreeCalculator(userName,resource);
tasks.add(calculator);
}
try {
for (Callable<String> callable : tasks) {
futures.add(exec.submit(callable));
}
for (Future<String> future : futures) {
String destUserName = future.get();
if(StringUtils.isNotBlank(destUserName)){
destNames.remove(destUserName);
}
}
} catch(Exception e){
LoggerHelper.err(ConcurrentAccountTreeCalculator.class, "计算人员权限出错", e);
}
return destNames;
}
static class AccountTreeCalculator implements Callable<String> {
private String userName;
private Resource resource;
public AccountTreeCalculator(String userName,Resource resource) {
this.userName = userName;
this.resource = resource;
}
@Override
public String call() {
try {
Account account = ServiceBeanFactory.getAccountService().getByName(userName);
if(account == null){
throw new SpmRuntimeException(String.format("Can't find user:%s", userName));
}
boolean hasPermisison = ServiceBeanFactory.getResourceService().hasPermission(resource, account);
if(hasPermisison) {
return account.getName();
}
} catch(Exception e){
LoggerHelper.err(this.getClass(), "计算人员权限出错", e);
}
return null;
}
}
}
这个实现的非常简单,我这里就不解释了,AccountTreeCalculator实现了Callable接口,这个里面实现具体的计算逻辑,然后将任务提交给ExecutorService来进行计算,future.get()会等待子线程返回结果,所以整个程序很好理解。
短小精悍但是比较有用。
分享到:
相关推荐
易语言多线程执行任务例程。
多线程执行任务具体实现方式;
NULL 博文链接:https://mammahao.iteye.com/blog/2226890
易语言多线程执行任务例程
声明BigJob 对 像(包括事件),创建BigJob 的实 例,通知对像执行任务,在对像的“ 开 始”事件中给用户一些提示,数字时钟”在不间断地显示当前时间。 不足之处:终止任务(关闭窗体)时 Activex.exe 部件需要...
C#,编写的多线程执行处理程序,同时执行多个任务,共大家参考。
(原创)asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一
使用线程池管理多线程上传,包含了文件拆分,文件分片多线程上传,单文件上传。多线程执行任务等待管理。拒绝直接new Thread创建新线程导致的诸多问题
主要实现了,多个线程任务在同时执行的情况下,保证线程任务顺序的问题。更通俗来说,就是保证Thread1一定在thread2,thread3之后才能执行。另外,代码里我写了详细的注释,和测试的效果,绝对让你能看懂。还有我传的...
多线程有很好的并发性即无序性,在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项目中如果...
Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...
代码采用多工作者多线程执行任务。通过暴露的方法往工作者传递消息,然后采用事件回调返回处理结果,实现的事件有OnThreadComplete,OnAddedTask,OnStart,OnSuccess,OnFailure,OnTimeout。 事件回调支持同步或...
2. 然后在线程池execute方法中,每个线程都执行一次ready.countDown()方法修改计数值 3. 在线程池中每个线程执行ready.countD
此前被面试问道一道面试题,B,C线程都有自己的任务,A线程要在B,C线程都结束后开始执行,并且不允许有A线程循环等待空耗CPU现象。
C#多线程实现进程管理(同步执行)
VC 创建多个 Thread多线程,用以执行不同任务的例子,运行程序后你可看到分别有红色、蓝色的小球,在沿各自不同的轨迹做运动,在代码中,我们创建了一个小球运动线程的主函数,分别用两个线程调用这个函数,但设定的...
spring定时任务 spring多线程的一个简单示例。
由三个类实现,写在了一个 Java 文件中:TaskDistributor 为任务分发器,Task 为待执行的任务,WorkThread 为自定的工作线程。代码中运用了命令模式,如若能配以监听器,用上观察者模式来控制 UI 显示就更绝妙不过了...
不精通线程、不擅长对多线程进行管理,就不可能在当今多CPU多核心的年代写出优秀的程序代码,软件的性能将会大打折扣。本文及其示例代码,诠释System.Classes.pas中的(多)线程 和System.SyncObjs.pas (深入应用...