多线程--Callable<T> 使用,及异步返回

在使用多线程编程是,会用到三种
一、Thread
使用时重写run方法,void
二、Runnable
使用时重写run方法,void
三、Callable
使用时重写run方法,有返回值 <T>
返回值有两种,FutureTask<T> 和 Future<T>
Future是一个接口,代表可以取消的任务,并可以获得任务的执行结果
FutureTask 是基本的实现了Future和runnable接口 实现runnable接口,说明可以把FutureTask实例传入到Thread中,在一个新的线程中执行。具体学习请百度。

由于futureTask.get() 是阻塞式等待结果返回,在每一次提交到线程池执行后就调用get()方法阻塞获取结果,这样获取方式仍然不是异步获取。进一步对代码进行修改,把每一个线程对应futrueTask对象暂存到一个list或者map中,这样在所有任务均已提交执行后再去获取执行结果,如下代码所示:

		//数据集合
		Page<OmOracleInstance> page = (Page<OmOracleInstance>) instanceMapper.selectByExample(example);
        // 创建一个大小为10的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //FutureTask 结果返回集合,用于存储异步返回结果
        List<FutureTask<JSONObject>> futureTaskList = new ArrayList<>();
        Stream<OmOracleInstance> stream = page.stream();
        stream.forEach(tmp -> {
            OmCntrOraInsDetail record = new OmCntrOraInsDetail();
            record.setInstanceId(tmp.getId());
            OmCntrOraInsDetail insDetail = insDetailMapper.selectOne(record);
            //查询当前连接数,查询实例用户数,查看当前运行状态
            JSONObject json = (JSONObject) JSONObject.toJSON(tmp);
            JSONObject json1 = (JSONObject) JSONObject.toJSON(insDetail);
            json1.putAll(json);
            //多线程执行
            SearchThread thread = new SearchThread(json1);
            FutureTask<JSONObject> futureTask = new FutureTask<>(thread);
            //提交线程
            executorService.submit(futureTask);
            futureTaskList.add(futureTask);

        });
        //关闭连接池
        executorService.shutdown();
        //异步获取执行结果
        for(FutureTask<JSONObject> futureTask: futureTaskList ){
            try{
                array.add(futureTask.get());
            }catch (Exception e){
                log.error(e.getMessage(),e);
            }
        }

这样任务的执行是并行执行,获取结果是阻塞式获取,则服务运行的最长时间是最后执行完结果返回的时间,如果其中一个线程执行完成需要花费10s,但是其余99个线程在1s就已经执行完成,则获取主线程阻塞的时间是10s,如果更巧的是那个花费10s的线程刚好放在list的第一位,则其余99个线程的结果也需要在第10s之后才能够获取到,显然这存在一定的优化空间。

SearchThread 类 实现Callable<T>

	@Slf4j
	public class SearchThread  implements Callable<JSONObject> {

    private JSONObject json;

    public SearchThread(JSONObject json){
        this.json = json;
    }

    @Override
    public JSONObject call() throws Exception {
        //构造一个StringBuilder对象
        StringBuilder sb = new StringBuilder(json.getString("name"));
        //在指定的位置,插入指定的字符串
        sb.insert(0, "[");
        sb.insert(2,"]");
        //远程连接
        JSchSshUtils client = null;
        try{
            client = JSchSshUtilsFactory.createJschSession(json.getString("ip"), json.getString("username"),
                    json.getString("password"));//执行
            //查询当前连接数
            String linkers = client.execCommand(ShellEnum.INSTANCE_LINKERS.getCode());
            json.put("linkers",Integer.parseInt(linkers.replace("\n",""))-1);
            //查询当前运行状态
            String runStatus = client.execCommand("ps -ef|grep "+sb.toString()+" |wc -l");
            json.put("runStatus",runStatus.replace("\n",""));
            //查询实例用户数
//            String users = client.execCommand(ShellEnum.INSTANCE_USERS.getCode());
//            json.put("users",users.replace("\n",""));
//            json.put("result","success");

        }catch (Exception e){
            log.error(e.getMessage(),e);
            json.put("result","fail");
            json.put("msg",e.getMessage());
        }finally {
            JSchSshUtilsFactory.closeJschSession(client);
            log.info("关闭SSH连接");
        }
        return json;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值