Java线程池
1、为什么要使用线程池
构建一个线程开销很大,如果程序中涉及到大量临时线程,就不应该将业务逻辑单独放入一个线程中,而应该使用线程池。线程池中包含许多准备运行的线程,为线程池提供一个Runnable,就会有一个线程调用run方法。当run方法退出时,这个线程不会死亡,而是留在池中准备为下一个请求提供服务。
提高线程的利用率
提高响应速度
便于统一管理线程对象
可控制最大并发数
2、如何使用线程池
7 大核心参数:
1、corePoolSize 核心池的大小,目前上班的柜台数
2、maximumPoolSize 线程池最大线程数,所有的柜台数(包括上班和不上班的)
3、keepAliveTime:空闲线程的存活时间
4、unit:keepAliveTime 时间单位
5、workQueue:阻塞队列,等候区
6、threadFactory:线程工厂,生成线程对象
7、handler:拒绝任务策略
public class Test {
public static void main(String[] args) {
//线程池对象
ExecutorService executorService = new ThreadPoolExecutor(
2,
3,
1L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
for (int i = 0; i < 5; i++) {
executorService.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "===>办理业务");
});
}
//关闭连接,完成已经提交的任务,但不在接受新的任务
executorService.shutdown();
}
}
Executors 提供了三种快速创建线程池的方式
newSingleThreadExecutor():线程池中只有一个线程对象
newFixedThreadPool(5):线程池中有 5 个线程对象
newCachedThreadPool():线程池中线程对象随机分配,由电脑配置决定
public class Test {
public static void main(String[] args) {
//单例线程池,只有一个线程对象
// ExecutorService executorService = Executors.newSingleThreadExecutor();
// ExecutorService executorService = Executors.newFixedThreadPool(5);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10000; i++) {
final int temp = i;
executorService.execute(()->{
System.out.println(Thread.currentThread().getName() + ":" + temp);
});
}
executorService.shutdown();
}
}
handler 提供了四种拒绝策略
AbortPolicy 直接抛出异常
DiscardPolicy 放弃任务,不抛出异常
DiscardOldestPolicy 尝试与阻塞队列最前面的任务去争夺,不抛出异常
CallerRunsPolicy 谁调用谁处理
使用executorService.execute提交任务,是不会有返回值的
使用executorService.submit提交任务,会得到一个Future的返回值
public class Test {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
return "返回值";
}
};
Future<String> submit = executorService.submit(callable);
try {
System.out.println(submit.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
executorService.submit可以放Runnable、Callable的实现
文章评论