一、三大线程池
1)newFixedThreadPool(5);//一池五个线程,底层用阻塞队列
2)newSingleThreadExecutor();//一池一个线程底层用阻塞队列
3)newCachedThreadPool();//一池N个线程,底层用同步队列
底层均调用ThreadPoolExecutor,例子如下:
public static ExecutorService newFixedThreadPool(int var0, ThreadFactory var1) {
return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var1);
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory var0) {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var0));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());
}
public static ExecutorService newCachedThreadPool(ThreadFactory var0) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue(), var0);
}
newFixedThreadPool(5)
public static void main(String[] args) {
ExecutorService threadpool = Executors.newFixedThreadPool(5);//一池五个线程
//ExecutorService threadpool = Executors.newSingleThreadExecutor();//一池一个线程
//ExecutorService threadpool = Executors.newCachedThreadPool();//一池N个线程
//模拟10个用户来办理业务,每个用户是一个请求线程
try {
for(int i=1;i<=10;i++){
threadpool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t 办理业务");
});
}
TimeUnit.HOURS.sleep(100000);
} catch (Exception e) {
// TODO: handle exception
}finally{
threadpool.shutdown();
}
}
结果:
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-2 办理业务
pool-1-thread-3 办理业务
pool-1-thread-4 办理业务
pool-1-thread-5 办理业务
可以看到,只有5个线程进行
newSingleThreadExecutor()
public static void main(String[] args) {
//ExecutorService threadpool = Executors.newFixedThreadPool(5);//一池五个线程
ExecutorService threadpool = Executors.newSingleThreadExecutor();//一池一个线程
//ExecutorService threadpool = Executors.newCachedThreadPool();//一池N个线程
//模拟10个用户来办理业务,每个用户是一个请求线程
try {
for(int i=1;i<=10;i++){
threadpool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t 办理业务");
});
}
TimeUnit.HOURS.sleep(100000);
} catch (Exception e) {
// TODO: handle exception
}finally{
threadpool.shutdown();
}
}
结果:
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
可看到只有1个线程进行处理
newCachedThreadPool()
public static void main(String[] args) {
//ExecutorService threadpool = Executors.newFixedThreadPool(5);//一池五个线程
//ExecutorService threadpool = Executors.newSingleThreadExecutor();//一池一个线程
ExecutorService threadpool = Executors.newCachedThreadPool();//一池N个线程
//模拟10个用户来办理业务,每个用户是一个请求线程
try {
for(int i=1;i<=10;i++){
threadpool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t 办理业务");
});
}
TimeUnit.HOURS.sleep(100000);
} catch (Exception e) {
// TODO: handle exception
}finally{
threadpool.shutdown();
}
}
结果
pool-1-thread-1 办理业务
pool-1-thread-2 办理业务
pool-1-thread-3 办理业务
pool-1-thread-4 办理业务
pool-1-thread-5 办理业务
pool-1-thread-6 办理业务
pool-1-thread-7 办理业务
pool-1-thread-7 办理业务
pool-1-thread-8 办理业务
pool-1-thread-7 办理业务
可看到根据实际线程调用多个线程进行处理
二、线程池的几个重要参数:
public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5,
BlockingQueue<Runnable> var6, ThreadFactory var7,
RejectedExecutionHandler var8) {
this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
this.mainLock = new ReentrantLock();
this.workers = new HashSet();
this.termination = this.mainLock.newCondition();
if (var1 >= 0 && var2 > 0 && var2 >= var1 && var3 >= 0L) {
if (var6 != null && var7 != null && var8 != null) {
this.acc = System.getSecurityManager() == null
? null
: AccessController.getContext();
this.corePoolSize = var1;
this.maximumPoolSize = var2;
this.workQueue = var6;
this.keepAliveTime = var5.toNanos(var3);
this.threadFactory = var7;
this.handler = var8;
} else {
throw new NullPointerException();
}
} else {
throw new IllegalArgumentException();
}
1.corePoolSize:线程池中的常驻核心线程数
2.maximumPoolSize:线程池能够容纳同时执行的最大线程数
3.keepAliveTime:多余的空闲线程的存活时间(当前线程池数量超过corePoolSize时,当空闲
时间达到keepAliveTime值时,多余的空闲线程会被销毁直到只剩下
corePoolSize个线程为止)
4.unit:keepAliveTime的单位
5.workQueue:任务队列,被提交但尚未被执行的任务
6.threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的即可
7.handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数时如何来拒绝
三、拒绝策略:
AbortPolicy:直接抛出RejectedExecutionException异常,阻止系统正常运行
CallerRunsPolicy:"调用者运行"一种调节机制,改策略既不会抛弃任务,也不会抛出异常
而是将某些任务回退到调用者
DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交
DiscardPolicy:直接丢弃任务,不予任何处理也不抛异常。
例子:
public static void main(String[] args) {
//System.out.println(Runtime.getRuntime().availableProcessors());//CPU核数
ExecutorService threadpool = new ThreadPoolExecutor(2, 3,1L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
try {
for(int i=1;i<=15;i++){
threadpool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t 办理业务");
});
}
//TimeUnit.MILLISECONDS.sleep(10);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
threadpool.shutdown();
}
}
结果:
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-1 办理业务
pool-1-thread-2 办理业务
pool-1-thread-3 办理业务
java.util.concurrent.RejectedExecutionException: Task MyThreadPoolDemo$$Lambda
AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at MyThreadPoolDemo.main(MyThreadPoolDemo.java:55)
可以看到抛出了异常,但在实际使用中,抛出异常阻止运行是不合理的,那么根据实际可调用其他拒绝策略,在这便不一一演示,可自行演示测试。