jdk1.5中的实现Callable接口中实现call方法创建线程与之前Thread类中或Runnable接口中的重写/实现run方法的不同
首选call方法最大不同就是增加了抛出异常及其返回值的功能。
Callable接口与Future, 多线程并发情况下利用Future对象接收返回值,上代码。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestCallable {
public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newCachedThreadPool();
Callable<Integer> task1 = new Callable<Integer>(){
public Integer call() throws Exception{
System.out.println("task1 start working");
int result = 0 ;
for(int i = 1 ; i < 100 ; i+=2){
result += i;
Thread.sleep(100);
}
System.out.println("task1 end working");
return result;
}
};
Callable<Integer> task2 = new Callable<Integer>(){
public Integer call() throws Exception{
System.out.println("task2 start working");
int result = 0 ;
for(int i = 2 ; i <= 100 ; i+=2){
result += i;
Thread.sleep(100);
}
System.out.println("task2 end working");
return result;
}
};
Future<Integer> f1 = es.submit(task1);
Future<Integer> f2 = es.submit(task2);
System.out.println("main do sth");
int result = f1.get()+f2.get();
System.out.println(result);
es.shutdown();
}
}
@Override
public Map selectAllCountByFuture() throws Exception {
Map map = new HashMap();
// 1.开启多个线程
// 查询 性别
Future<Boolean> future1 = ThreadPollUtil.executor.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
List<Map> maps = selectBySexCount();
map.put("sex",maps);
return true;
}
});
// 查询 地区分布
Future<Boolean> future2 = ThreadPollUtil.executor.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
List<Map> province = selectByProvince();
map.put("province",province);
return true;
}
});
// 查询 注册量
Future<Boolean> future3 = ThreadPollUtil.executor.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Map map1 = selectByDayCount();
map.put("count",map1);
return true;
}
});
// 代表全部线程执行完毕
if (future1.get() && future2.get() && future3.get()){
return map;
}
return null;
}
ThreadPollUtil 工具类
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPollUtil {
/**
* IO密集型任务 (常出现于线程中:数据库数据交互、文件上传下载、网络数据传输等等 能够体现多核处理器的优势)
* CPU密集型任务 (常出现于线程中:复杂算法 能体现CPU版本的优势)
*/
private static int corePoolSize = Runtime.getRuntime().availableProcessors();
/**
* public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
* TimeUnit unit,BlockingQueue<Runnable> workQueue)
* corePoolSize用于指定核心线程数量
* maximumPoolSize指定最大线程数
* keepAliveTime和TimeUnit指定线程空闲后的最大存活时间
* workQueue则是线程池的缓冲队列,还未执行的线程会在队列中等待
* 监控队列长度,确保队列有界
* 不当的线程池大小会使得处理速度变慢,稳定性下降,并且导致内存泄露。如果配置的线程过少,则队列会持续变大,消耗过多内存。
* 而过多的线程又会 由于频繁的上下文切换导致整个系统的速度变缓——殊途而同归。队列的长度至关重要,它必须得是有界的,这样如果线程池不堪重负了它可以暂时拒绝掉新的请求。
* ExecutorService 默认的实现是一个无界的 LinkedBlockingQueue。
*/
public static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000));
}
还有countdownlatch的使用
@Override
public Map selectAllCountByThread() throws InterruptedException {
Map map = new HashMap();
// 1.创建任务计数器 参数为设置任务数量
CountDownLatch countDownLatch = new CountDownLatch(3);
// 2.开启三个线程 分别执行三个查询
// 查询 性别信息
ThreadPollUtil.executor.submit(new Runnable() {
@Override
public void run() {
List<Map> maps = selectBySexCount();
// 得到查询结果
map.put("sex",maps);
// 计数器减一
countDownLatch.countDown();
}
});
// 查询 地区分布
ThreadPollUtil.executor.submit(new Runnable() {
@Override
public void run() {
List<Map> maps = selectByProvince();
// 得到查询结果
map.put("province",maps);
// 计数器减一
countDownLatch.countDown();
}
});
// 查询 注册量
ThreadPollUtil.executor.submit(new Runnable() {
@Override
public void run() {
Map map1 = selectByDayCount();
map.put("count",map1);
countDownLatch.countDown();
}
});
// await() 当计数器为0的时候 主线程向下执行 没有这一步的话,如果一旦主线程向下执行
// return map map中可能有的开启的线程还没有执行完毕,即返回的不是线程执行后的结果
countDownLatch.await();
return map;
}
countDownLatch 和 Future 区别
countDownLatch 更加的简洁 判断所有任务是否执行成功的时候 不需要做复杂的逻辑判断
这辈子坚持与不坚持都不可怕,怕的是独自走在坚持的道路上!!!
创建线程