多线程的粗浅学习ing

https://www.cnblogs.com/sachen/p/7401959.html
线程池的种类,区别和使用场景
newCachedThreadPool:适用:执行很多短期异步的小程序或者负载较轻的服务器; 高并发 大数据的时候
可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool:适用:执行长期的任务,性能好很多  多用于数据库执行时
定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newSingleThreadExecutor: 适用:一个任务一个任务执行的场景
单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
NewScheduledThreadPool: 适用:周期性执行任务的场景    
定长线程池,支持定时及周期性任务执行。

线程池任务执行流程:

当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭


public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), defaultHandler);

}

corePoolSize:线程池的核心线程数,线程池中运行的线程数也永远不会超过 corePoolSize 个,默认情况下可以一直存活。可以通过设置allowCoreThreadTimeOut为True,此时 核心线程数就是0,此时keepAliveTime控制所有线程的超时时间。

maximumPoolSize:线程池允许的最大线程数;

keepAliveTime: 指的是空闲线程结束的超时时间;

unit :是一个枚举,表示 keepAliveTime 的单位;

workQueue:表示存放任务的BlockingQueue<Runnable队列 

 

 

@Repository    具有类似用途和功能的@Component注解的特化,为Dao提供了额外的好处,将Dao导入IOC容器,使未经检验的异常有资格转换为Spring DataAccessException

 

线程池:

https://www.jianshu.com/p/210eab345423

 

执行任务execute的核心逻辑

 

线程池运行的四个阶段:

 

总结:ThreadPoolExecutor基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程相当于消费者;

    Executors提供了四种基于ThreadPoolExecutor构造线程池模型的方法,除此之外,我们还可以直接继承ThreadPoolExecutor,重写beforeExecute和afterExecute方法来定制线程池执行任务;

    使用有界队列还是无界队列需要根据具体情况考虑,工作队列的大小和线程的数量;

    拒绝策略推荐使用CallerRunsPolicy,该策略不会抛弃任务,也不会抛出异常,而是将任务回退到调用者线程中执行;

 

 

 

 

 

 

 

多线程,最简单的用法就是多个线程。

多个线程一起跑就叫多线程,,,,emmmm,好尬。

一般用于处理多个任务或多个方法时,这个任务需要处理的时间还比较长,可能会产生多个任务,如果正常的采用for循环的形式进行执行,这样需要等到所有任务都执行完系统才会执行下一步 ,这样会造成许多的时间浪费,这算是同步吧,。这时候就需要采用异步的方法,将这些任务去执行,但是不需要关心后期执行过程,(无返回值要求),这样就不会造成长时间的等待了。这种场景需要用多线程。

还有一种情况,一般的采用runnable接口的多线程,run方法无返回值,但是需要采用多线程,有需要使用这个方法的返回值用于其他计算,这时候需要采用callable接口。可以得到返回值。

 

1.最简单的多个线程一起跑的多线程。(不知道算不算多线程啦)

设计 4 个线程,其中两个线程每次对 j 增加 1,另外两个线程
对 j 每次减少 1。写出程序。
以下程序使用内部类实现线程,对 j 增减的时候没有考虑顺序问题。
public class ThreadTest {
 private int j;
 public static void main(String args[]){
 ThreadTest tt=new ThreadTest();
 Inc inc=tt.new Inc();
 Dec dec=tt.new Dec();

 for(int i=0;i<2;i++){
  Thread t=new Thread(inc);
  t.start();
  t=new Thread(dec);
  t.start();
 }
}
private synchronized void inc(){
 j++;
 System.out.println(Thread.currentThread().getName()+"-inc:"+ j);
}
private synchronized void dec(){
 j--;
 System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable{
 public void run(){
 for(int i=0;i<100;i++){
  inc();
 }
 }
}
class Dec implements Runnable{
public void run(){
 for(int i=0;i<100;i++){
 dec();
 }
}
}

这个还算是比较经典的多线程算法题吧,

2,采用ExecuteService形式,使用多线程,runnable

https://blog.csdn.net/wanghao_0206/article/details/76460877

这个挺清楚的。

ExecutorService executorService = null;

List<Map<String,Object>> applys = Dao.selectList(msSupplementMapper+"queryLoanApplyAndResult");
if(CollectionUtils.isEmpty(applys)){
    return ;
}
executorService = Executors.newFixedThreadPool(applys.size() > 20 ? 20 : applys.size());
for(final Map<String,Object> apply : applys){

    final int status = Integer.parseInt(apply.get("status").toString());
    final int mainStatus = Integer.parseInt(apply.get("mainStatus").toString());

    executorService.execute(new Runnable() {
        @Override
        public void run() {
            // 放款申请成功 || 已发起放款申请 || 放款成功无正式还款计划 -- 发送放款结果查询
            if(
                    (MsStatus.LOAN_APPLY.getCode() == mainStatus && MsStatus.LOAN_APPLY_SUCCESS.getCode() == status) )){

                queryLoanResult(apply.get("projectId").toString());

            }else{

                loanApply(apply.get("projectId").toString());

            }
        }
    });

}

3,采用ExecutorService形式,利用future。

  List<Future<PayableSource>> futureList = new ArrayList<>(sumBeginningList.size());

     for(SumBeginning sumBeginning : sumBeginningList){
       logger.debug("===== 循环遍历 sumBeginning =====");
       ChargeBo<SumBeginningQo> chargeBoToRefer = chargeBo.clone();
chargeBoToRefer.setOperator(UserUtil.getCurrentUser(false));
sumBeginningQo = new SumBeginningQo();
sumBeginningQo.setId(sumBeginning.getId());
chargeBoToRefer.setPayableSourceQueryObj(sumBeginningQo);
logger.debug("===== 进入chargeService 逻辑 =====");
futureList.add(executorService.submit(new ChargeService(chargeBoToRefer, SUM_BEGINNING_SERVICE)));
     }
     logger.debug("<<<<<SumBeginningService.charge");
     return futureList;
public ChargeService(ChargeBo chargeBo, PayableService payableService){
   this.chargeBo = chargeBo;
   this.payableService = payableService;
}
new ChargeService 是实现的callable接口,在call方法实现了返回值。
@Override
public PayableSource call()  throws Exception{
   logger.debug(">>>>>ChargeService.call");
   RPermitExpirableSemaphore semaphore = null;
   String permitId = null;
   try{
      PayableSource queryObj = chargeBo.getPayableSourceQueryObj();

      PayableSource payableSource = null;
      if(queryObj instanceof SumBeginningPlusQo){
         payableSource = payableService.getPayableSourcePlus(queryObj.getId(), true);
         logger.debug("===== 代偿跳过扣款验证 =====");
      }else{
         payableSource = payableService.getPayableSource(queryObj.getId(), true);
         payableService.validatePayable(payableSource);
      }
return payableSource;
}catch (Exception e){
   logger.error("===== ChargeService.call出现异常:", e);
   Dao.rollback();
   if(e instanceof ActionException){
      throw e;
   }else{
      throw new ActionException(e.getMessage(), e);
   }
}finally {
   Dao.close();
   if(semaphore != null && permitId != null){
      semaphore.release(permitId);
   }
}

上边list采用的Future模式,用来承接callable方法的,具体的还不太了解。。。emmmm。

了解彻底理解Java的Future模式,,

https://www.cnblogs.com/cz123/p/7693064.html

。好好学习,差的还有点多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值