线程Java的两种方式_多线程(java和guava两种方式):
1、Java
当要使用线程去执行一个任务时,可以使用ExecutorService.submit(new Callable);
这样可以不影响其他的业务的执行,但是在线程中的异常不能捕获到,也不能知道线程的执行情况;
首先创建一个固定大小堵塞的线程池:
public class O2oThreadPoolExecutor extends ThreadPoolExecutor {
private static final Logger logger = LoggerFactory.getLogger(O2oThreadPoolExecutor.class);
private static ExecutorService executor = new O2oThreadPoolExecutor(2, 100, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue(500), new RejectedExecutionHandlerImpl());
private static int MAX_CONCURRENCY = 0;
public static ExecutorService getInstance(){
return executor;
}
public O2oThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue workQueue, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
}
@Override
public void shutdown() {
printThreadPoolInfo("Shutdown");
super.shutdown();
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
printThreadPoolInfo("Before execute");
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
printThreadPoolInfo("After execute");
super.afterExecute(r, t);
}
private void printThreadPoolInfo(String subject){
int runningTasks = getActiveCount();
MAX_CONCURRENCY = runningTasks > MAX_CONCURRENCY ? runningTasks : MAX_CONCURRENCY;
logger.info("{}, pool size:{}, running task:{}, pending task:{}, max concurrency:{}.",
subject,getPoolSize(),getActiveCount(),getQueue().size(),MAX_CONCURRENCY);
}
}
然后实现RejectedExecutionHandler,主要是当拒绝之后,重新put进去,防止丢失
public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if(!executor.isShutdown()){
try{
executor.getQueue().put(r);
}catch(InterruptedException e){
}
}
}
}
在然后定义线程需要执行的任务,实现Callable接口
public class TradeStatisticsTask implements Callable {
private final static Log logger = LogFactory.getLog(TradeStatisticsTask.class);
private UserTradeStatisticsRequestDTO userTradeStatisticsRequestDTO;
private UserTradeStatisticsService userTradeStatisticsService;
private static final String TRADE_STATISTICS_CHANGE_LOCK = "trade_statistics_change_lock";
private static final int TRADE_STATISTICS_CHANGE_LOCK_EXPIRE = 1;
public TradeStatisticsTask(UserTradeStatisticsService userTradeStatisticsService,UserTradeStatisticsRequestDTO userTradeStatisticsRequestDTO){
this.userTradeStatisticsRequestDTO = userTradeStatisticsRequestDTO;
this.userTradeStatisticsService = userTradeStatisticsService;
}
@Override
public Long call() throws Exception {
logger.info("TradeStatisticsTask的insert任务:"+JSONUtils.toJsonString(this.userTradeStatisticsRequestDTO));
O2oLock lock = new O2oRedisLock(TRADE_STATISTICS_CHANGE_LOCK + userTradeStatisticsRequestDTO.getBankCardNumber()+userTradeStatisticsRequestDTO.getUserId(),
TRADE_STATISTICS_CHANGE_LOCK_EXPIRE);
if (lock.tryLock(TRADE_STATISTICS_CHANGE_LOCK_EXPIRE)) {
try{
//先判断在统计数据中是否有该用户、银行卡、当天的记录,如果没有,则插入,否则更新
Long userId = this.userTradeStatisticsRequestDTO.getUserId();
String bankCardNumber = this.userTradeStatisticsRequestDTO.getBankCardNumber();
String tradeYearMouthDay = this.userTradeStatisticsRequestDTO.getTradeYearMouthDay();
UserTradeStatistics tradeParam = userTradeStatisticsService.queryUserTradeByUserIdAndBankCardNum(tradeYearMouthDay, userId, bankCardNumber);
if(tradeParam != null){
logger.info("需要更新的tradestatistics是:"+JSONUtils.toJsonString(tradeParam));
BigDecimal dayAmount = this.userTradeStatisticsRequestDTO.getDayAmount().add(tradeParam.getDayAmount());
tradeParam.setDayAmount(dayAmount);
userTradeStatisticsService.update(tradeParam);
return tradeParam.getId();
}else{
logger.info("开始插入统计数据");
UserTradeStatistics userTradeStatistics = new UserTradeStatistics();
BeanMapper.copy(this.userTradeStatisticsRequestDTO, userTradeStatistics);
return userTradeStatisticsService.insert(userTradeStatistics);
}
}catch(Exception e){
logger.error("插入更新数据失败", e);
return null;
}
}else{
logger.info("被锁住了。。。。");
return null;
}
}
}
最后在业务层,调用线程执行
TradeStatisticsTask task = new TradeStatisticsTask(userTradeStatisticsService,userTradeStatisticsRequestDTO);
O2oThreadPoolExecutor.getInstance().submit(task);
2、guava
前面三步和java一样,只是在业务层处理层改成了guava的方式去处理线程的调用,使用guava调用是可以抓到线程运行时的异常、并知道线程是否运行成功;
TradeStatisticsTask task = new TradeStatisticsTask(userTradeStatisticsService,userTradeStatisticsRequestDTO);
// O2oThreadPoolExecutor.getInstance().submit(task);
//方法1:可以直接得到Future的返回值,或者处理错误情况
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(O2oThreadPoolExecutor.getInstance());
final ListenableFuture future = executorService.submit(task);
Futures.addCallback(future, new FutureCallback() {
@Override
public void onFailure(Throwable e) {
logger.error("线程执行失败", e);
}
@Override
public void onSuccess(Long message) {
logger.info("receive message :" + message);
}
});
//方法2:监听Future,对原生Future扩展增强,ListenFuture可以帮忙检测Future是否执行完成,如果完成就自动调用回调函数
future.addListener(new Runnable(){
@Override
public void run() {
try {
logger.info("receive message :" + future.get());
} catch (Exception e) {//主要是InterruptedException、ExecutionException出错
logger.error("get message error :", e);
}
}
}, executorService);
线程Java的两种方式_多线程(java和guava两种方式):相关推荐
- java 监控对象是什么_多线程-Java中的对象监视器是什么意思? 为什么要使用这个词?...
多线程-Java中的对象监视器是什么意思? 为什么要使用这个词? 在阅读有关Java线程的文章时,我经常注意到这样的表达:"当前线程是该对象的监视器的所有者". 我的意思是:线程有 ...
- 西门子精智comfort系列面板下载程序的几种方法_参考手册(以太网+PN+USB方式)
西门子精智comfort系列面板下载程序的几种方法_参考手册(以太网+PN+USB方式) 以太网及 PN/IE 方式下载 下载要求 以太网电缆 交叉线: 对电缆的具体要求最好采用T568B的交叉线序标 ...
- 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目
王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...
- JAVA共有几种窗体布局方式_在Java GUI程序开发中常见的三种布局管理器是什么
答:FlowLayout 流式布局,从左到右,如果到边界就换行再从左到右. BorderLayout 边界布局(默认布局方式),按东西南北中五个方向来布局,默认是中.后设置在同样位置的控件会覆盖之前的 ...
- java中的单例_细说Java中的几种单例模式
在Java中,单例模式分为很多种,本人所了解的单例模式有以下几种,如有不全还请大家留言指点: 饿汉式 懒汉式/Double check(双重检索) 静态内部类 枚举单例 一.饿汉式 image 饿汉式 ...
- java 同步解决不安全类_「JAVA」Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好...
线程不安全 线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来:示例代码如下: public class ImplementsDemo { public static void ...
- java ee 的使用方法_改善Java EE生产支持技能的8种方法
java ee 的使用方法 参与Java EE生产支持的每个人都知道这项工作可能很困难. 7/24寻呼机支持,多个事件和错误修复(要定期处理),来自客户和管理团队的压力,要求它们尽快解决生产问题并防止 ...
- java获取系统时间的几种方法_获取当前时间的几种方法整理(Java)
在java中有很多方法可以取到系统时间,记一下最简单的那种 //使用Calendar 获取当前日期和时间 Calendar calendar = Calendar.getInstance(); // ...
- python猜拳游戏三局两胜制_猜拳游戏三局两胜------java实现代码
package com.javasm.exerices02; import java.util.ArrayList; import java.util.List; import java.util.R ...
最新文章
- 归一化激活层的进化:谷歌Quoc Le等人利用AutoML 技术发现新型ML模块
- 干货丨从起源到具体算法,这是一份适合所有人读的深度学习综述论文
- 【记录】python多线程的使用 线程同步(LOCK和RLOCK) python与mysql数据库交互实现增加和查找 python的格式化输出
- 如何更改ubuntu的用户密码
- Dlib与OpenCV图片转换
- AcWing 499. 聪明的质监员
- mysql y_关于MySQL中Y和~问题
- 数据库事务的四个隔离级别
- webstore报 ESLint: Expected space or tab after '//' in comment.(spaced-comment)
- JavaScript学习(四十八)—原型对象的增删改查
- 数据--第37课 - 线索化二叉树
- [ 淘宝商城 ] 商城SEO
- c语言程序设计身高体重测评系统,C语言程序设计验.doc
- 1 Apache启动失败,请检查相关配置 √MySQL5 1已启动 解决方案
- CF546C. Soldier and Cards(队列+模拟)
- Codeforces Round #801 (Div. 2) D2(思维/dfs)
- 手把手系列--验证自己编写的STM32H750XBH6_ArtPi平台Keil MDK Flash下载算法
- 百度关键字优化精灵下载-批量免费百度关键词优化软件
- hsqldb mysql 语法_[spring batch]建表语句(hsqldb改mysql)
- 报表中的多维数据分析,并没有你想象的那么难!
热门文章
- Vite与webpack优势
- Java黑皮书课后题第3章:*3.5(给出将来的日期)编写一个程序,提示用户输入代表今天日期的数字(周日0周一1周二2)同时用户输入一个今天之后的天数代表将来某天的数字,然后显示这天是周几
- 2013年完美世界校园招聘笔试题
- KMP算法详解及各种应用
- 【git】强制覆盖本地代码(与git远程仓库保持一致)
- spring 之 init-method InitializingBean
- Ubuntu 16.04系统下配置cocos2dx-3.10
- 用UltraEdit判断打开文件的编码类型 用UltraEdit或notepad记事本查看文件编码格式 用UltraEdit查看当前文件编码...
- 解决cell循环利用造成的重复勾选
- storm安装笔记以及提交拓扑任务