书接上篇一个简单的Runnable
对比Runable
和Callable
区别
返回结果
:Runable没
返回结果,Callable有
返回结果异常
: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完成