目录
方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。
什么是线程池?
答:线程池就是一个可以复用线程的技术。
不使用线程池的问题
答:用户每次发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会影响系统的性能。
创建线程池
JDK5.0起提供了代表线程池的接口:ExecutorService.
如何创建线程池对象?
方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。
方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象。(不推荐,后面会说)
方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepaliveTime,
TimeUnit unit,
BlockingQueue<Runnable>workQueue,
ThreadFactory thread Factory,
RejectedExecutionHandler)
使用指定的初始化参数创建一个新的线程池对象。
参数一:corePooLSize:指定线程池的核心线程的数量。
参数二:maximumPoolSize:指定线程池的最大线程数量。
参数三:keepAliveTime:指定临时线程的存活时间。
参数四:unit:指定临时线程存活或时间单位(秒,分,时,天)
参数五:workQueue:指定线程池的任务队列。
参数六:threadFactory:指定线程池的线程工厂。
参数七:handler:指定线程池的任务拒绝策略(线程都在忙,任务队列也满的时候,新任务就会拒绝)
package ExecutorServicedemo1;
import java.util.concurrent.*;
public class ExecutorServicedemo2 {
public static void main(String[] args) {
// 使用正确的构造函数签名创建线程池
ExecutorService executorServices = new ThreadPoolExecutor(
3, // 核心线程数
5, // 最大线程数
10, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(3), // 任务队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
MyRunnable myRunnable = new MyRunnable();
executorServices.execute(myRunnable);
executorServices.execute(myRunnable);
executorServices.execute(myRunnable);
Future<String> f1 = executorServices.submit(new MyCallable(10));
try {
System.out.println(f1.get());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
package ExecutorServicedemo1;
public class MyRunnable implements Runnable{
@Override
public void run()
{
for(int i = 0; i < 10; i++)
{
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
package ExecutorServicedemo1;
import java.util.concurrent.Callable;
public class MyCallable implements Callable<String> {
private int n;
public MyCallable(int n) {
this.n = n;
}
public String call() throws Exception {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += i;
}
return Thread.currentThread().getName() + ":" + sum;
}
}
什么时候开始创建临时线程?
新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建线程。
什么时候拒绝策略?
核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。
通过Executors创建线程池
是一个线程池的工具类,提供了很多静态方法用来返回不同特点的线程池对象。
策略 | 说明 |
ThreadPoolExecutor.AbortPolicy() | 丢弃任务并抛出RejectedExecutionExeception异常。是默认的策略 |
ThreadP0olExecutor.DisCardPolicy() | 丢弃任务,但是不抛出异常,这就是不推荐的做法。 |
ThreadPoolExecutor.DisCardOldstPolicy() | 抛弃队列中等待最久的任务,然后将当前任务加入队列中。 |
ThreadPoolExecutor.CallerRunsPolicy() | 由主线程负责任务的run()方法而绕过线程直接执行。 |
方式二:通过Executors创建线程池。
方法名称 | 说明 |
public static ExecutorService newFixedThreadPool(int nThreads) | 创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程会补充一个新线程替代它。 |
public static ExecutorService newSingleThreadPool() | 创建只有一个线程的线程池对象, 该线程出现异常而结束,那么线程池会补充一个新线程。 |
public static ExecutorService newCachedThreadPool() | 线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉。 |
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) | 创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。 |
ExecutorService a= Executors.newFixedThreadPool(3);
Executors可能存在的陷阱
大型并发系环境中使用Executors去创建,如果不注意,可能会出现系统风险,而是通过ThreadPoolExecutor。
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » java:线程池
发表评论 取消回复