ExecutorService中submit的理解

package com.haizhi.gap.search.offline.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableDemo {
        public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<String>> resultList = new ArrayList<>();

        //创建10个任务并执行
        for (int i = 0; i < 10; i++) {
        //使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
        Future<String> future = executorService.submit(new TaskWithResult(i));
        //将任务执行结果存储到List中
            System.out.println("执行结束" + i);
            resultList.add(future);
        }
            System.out.println("有几个返回结果" + resultList.size());
        //遍历任务的结果
        for (Future<String> fs : resultList) {
        try {
            //重点: 在executorService提交执行后,如果该线程还未执行完, fs.get()是阻塞的,没有返回结果的,注意,重点内容
            //在这里就可以做进度处理,10个进程中,已经有2个处理完成了。
             System.out.println(fs.get());     //打印各个线程(任务)执行的结果
        } catch (InterruptedException e) {
        e.printStackTrace();
        } catch (Exception e) {
           e.printStackTrace();
        } finally {
        //启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。
        executorService.shutdown();
        }
        }
        }
        }


class TaskWithResult implements Callable<String> {
    private int id;

    public TaskWithResult(int id) {
        this.id = id;
    }

    public String call() throws Exception {
        System.out.println(  Thread.currentThread().getName() +"      call()方法被自动调用,干活!!!");
           //一个模拟耗时的操作
        for (int i = 999999; i > 0; i--) ;

        return   "call()方法被自动调用,任务的结果是:" + id + "    " + Thread.currentThread().getName();
    }
}

  问题:一个请求的计算任务时间比较长,很有可能在响应时间之内,结果也没有返回。

   解决方法:将一个请求分为10个线程去请求,最后将10个线程请求后的结果汇总。怎么将一个请求分为10个线程去请求呢,比如说请求条件是A集合,B集合。请求算法是找出A集合中的元素和B集合中元素的关系。就可能将线程的请求条件变为A中的一个元素和B集合中的一个元素。

    在这个解决方法中,遇到一个问题。怎么计算这个任务计算的进度。

    解决方法:在处理任务计算进度的时候,根据线程阻塞的时间的不同,每返回一个线程返回结果的时候不同。当线程处理完结果后,将处理完成请求个数加1,统计返回结果的线程数,来除以请求的总数,等到的就是进度了。即在返回对象中定义一个AtomicInteger。在计算进度时,才用定时器定时更新进度。定时器采用Java.Util.Timer来实现。

   -----------------------  定时器 Timer的用法 —————————————

现在项目中用到需要定时去检查文件是否更新的功能。timer正好用于此处。

用法很简单,new一个timer,然后写一个timertask的子类即可。

代码如下:

package comz.autoupdatefile;  
  
import java.util.Timer;  
import java.util.TimerTask;  
  
public class M {  
    public static void main(String[] args) {  
        // TODO todo.generated by zoer  
        Timer timer = new Timer();  
        timer.schedule(new MyTask(), 1000, 2000);  
    }  
}  
  
class MyTask extends TimerTask {  
  
    @Override  
    public void run() {  
        System.out.println("dddd");  
  
    }  
  
} 

这样,就可以在1秒钟之后开始执行mytask,每两秒钟执行一次。

当然,timer的功能也可以通过自己构造线程,然后在线程中用sleep来模拟停止一段时间,然后再执行某个动作。

其实,看一下timertask的源码就立即可以知道,timertask就是实现了runnable接口的。也就是说,通过timer来间隔一段时间执行一个操作,也是通过一个线程来做到的。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值