需要返回值的多线程
其中 Callable 为有返回值的多线程接口
Callable和Runnable的区别如下:
1. Callable定义的方法是call,而Runnable定义的方法是run。
2. Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。
3. Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public Result<List<Account>> getAllAccountInfo(String account) {
// 线程安全的list
//CopyOnWriteArrayList 并发容器
final List<Account> resultList = new CopyOnWriteArrayList<>();
List<SubCategory> subCategoryList = subCategoryDao.querySubCategory();
class Runner implements Callable<Object> {
private String account;
private Integer distId;
private String distName;
@Override
public Object call() {
long t1 = System.currentTimeMillis();
Result<Account> result = accountService.getAccount(distId, account);
logger.info("区组" + distId + "耗时:" + (System.currentTimeMillis() - t1));
if (null != result.getResult()) {
result.getResult().setDistName(distName);
resultList.add(result.getResult());
}
return null;
}
Runner(String account, Integer distId ,String distName) {
this.account = account;
this.distId = distId;
this.distName = distName;
}
}
List<Callable<Object>> runnables = new ArrayList<>();
for (SubCategory subCate : subCategoryList) {
Callable<Object> runnable = new Runner(account, Integer.parseInt(subCate.getDistId()),subCate.getDistName());
runnables.add(runnable);
}
ExecutorService service = Executors.newFixedThreadPool(subCategoryList.size());
try {
service.invokeAll(runnables, 5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
logger.error(e.toString());
}
Result<List<Account>> result = new Result<List<Account>>();
List<Account> strList = new ArrayList<>(resultList);
result.setResult(strList);
result.setStatusCode(ResultType.SUCCESS);
service.shutdown();
return result;
}
不需要返回值的多线程
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ParseElinkTheradPool {
private static ExecutorService threadPool;
static{
threadPool = Executors.newFixedThreadPool(5);
}
/**
* 添加任务
* @param task
* @return
*/
public static boolean addTask(Runnable task){
threadPool.execute(task);
return true;
}
}
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import cn.gyyx.hrms.business.BusinessUtils;
import cn.gyyx.hrms.business.TimerBusiness;
import cn.gyyx.hrms.model.TMailLink;
import cn.gyyx.hrms.timer.runnable.ParseElinkRunnable;
@Component
public class ParseElinkTimer {
private static final Logger log = LoggerFactory.getLogger(ParseElinkTimer.class);
/**
* 解析应聘者简历定时器
*/
@Scheduled(cron = "0 0/1 * * * ?")
public void runTask() {
//获取业务对象
TimerBusiness timerBusinessImpl = BusinessUtils.getBusinessImpl("timerBusinessImpl");
List<TMailLink> links = timerBusinessImpl.queryAllWaitTaskForMailLink();
for(TMailLink link : links){
ParseElinkTheradPool.addTask(new ParseElinkRunnable(link));
try{
link.setLinkStatus(1);//正在下载
link.setLinkCount(link.getLinkCount() + 1);
// 更新链接记录
timerBusinessImpl.updateMailLinkInfo(link);
}catch(Exception e){
log.error(link.getLinkName() + "解析异常!");
}
}
}
}
public class ParseElinkRunnable implements Runnable{
public void run() {
//执行你的业务逻辑.....
}
}