一个简单的Callable

书接上篇一个简单的Runnable

对比RunableCallable区别

  1. 返回结果Runable没返回结果,Callable有返回结果
  2. 异常Runable的run方法不能抛出异常只能内部消化,Callable的call方法可以抛出异常

Thread+FutureTask实现

定义一个任务类实现Callable

package com.example.demo.threadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

@Slf4j
@Component
public class MyCallable implements Callable {
    @Override
    public Map<String,Object> call() throws Exception {
        log.info("子任务开始");
        Thread.sleep(2000);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("a","a");
        log.info("子任务结束");
        return hashMap;
    }
}

调用任务类,不获取返回结果,子线程不阻塞

package com.example.demo.controller;
import com.example.demo.threadPool.MyCallable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@Slf4j
@RestController
public class OneController {
    @GetMapping("/getBaidu")
    public String getBaiDu(String string) throws ExecutionException, InterruptedException {
        Callable<HashMap<String, Object>> myCallable = new MyCallable();
        FutureTask<HashMap<String, Object>> futureTask = new FutureTask<>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        log.info("所有任务结束");
        return "over";
    }
}

调用任务类,获取返回结果,子线程阻塞
获取返回结果需要调用FutureTask.get()方法实现,会阻塞主线程直到获取‘将来’结果。当不调用此方法时,主线程不阻塞

package com.example.demo.controller;

import com.alibaba.fastjson.JSON;
import com.example.demo.threadPool.MyCallable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@Slf4j
@RestController
public class OneController {
    @GetMapping("/getBaidu")
    public String getBaiDu(String string) throws ExecutionException, InterruptedException {
        Callable<HashMap<String, Object>> myCallable = new MyCallable();
        FutureTask<HashMap<String, Object>> futureTask = new FutureTask<>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        log.info("子任务返回数据:"+ JSON.toJSONString(futureTask.get()));
        log.info("所有任务结束");
        return "over";
    }
}

至此简单的Thread+FutureTask完成

线程池+FutureTask实现
自定义线程池MyThreadPool

package com.example.demo.threadPool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyThreadPool {
    public static ThreadPoolExecutor newInstance() {
        return SingletonHolder.threadPoolExecutor;
    }
    /**
     * 定义cpu核数+3数量的线程池
     * 静态内部类方式使用时创建,线程安全
     */
    public static class SingletonHolder{
        private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors()/2;
        private static final int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors();
        private static final int QUEUE_CAPACITY = 1000;
        private static final Long KEEP_ALIVE_TIME = 1L;
        private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(QUEUE_CAPACITY),
                new ThreadPoolExecutor.CallerRunsPolicy());
    }
}

定义一个任务类实现Callable同上这里不重复
调用任务类,不获取返回结果,子线程不阻塞获取返回结果子线程阻塞,跟上面一样,这里不过多写

package com.example.demo.controller;

import com.alibaba.fastjson.JSON;
import com.example.demo.threadPool.MyCallable;
import com.example.demo.threadPool.MyThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.concurrent.*;

@Slf4j
@RestController
public class OneController {
    @GetMapping("/getBaidu")
    public String getBaiDu(String string) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor executor = MyThreadPool.newInstance();
        MyCallable myCallable = new MyCallable();
        FutureTask<HashMap<String, Object>> futureTask = new FutureTask<>(myCallable);
        executor.submit(futureTask);
        executor.shutdown();
        //log.info("子任务返回数据:"+ JSON.toJSONString(futureTask.get()));
        log.info("所有任务结束");
        return "over";
    }
}

至此简单的线程池+FutureTask完成

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值