线程池(重点)
池化技术
事先准备好一些资源,优化系统资源地使用,有人要用就来我这取,用完之后还给我
好处
- 降低资源地消耗
- 提高响应速度
- 方便管理
线程复用,可以控制最大并发数,管理线程
package com.unsafe;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorsPro {
public static void main(String[] args) {
// Executors 工具类 3大方法
// ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
// ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的 遇强则强
for (int i = 1; i <= 50; i++) {
final int tmp =i;
// 使用线程池来创建线程
executorService.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok"+tmp);
});
}
//线程池用完要关闭
executorService.shutdown();
}
}
7大参数
3大方法的源码中可以看出:
new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
三大方法的本质是实例化ThreadPoolExecutor对象,推荐这样使用
- 核心线程池大小(int corePoolSize,
- 最大核心核心线程池大小 int maximumPoolSize,
- 超时了没有人调用就会释放 long keepAliveTime,
- 超时单位 TimeUnit unit,
- 阻塞队列 BlockingQueue workQueue,
- 线程工厂 ThreadFactory threadFactory,
- 拒绝策略 RejectedExecutionHandler handler)
4种拒绝策略
- // 策略一 new ThreadPoolExecutor.AbortPolicy() 满了还有线程进来就不处理这个线程,抛出异常
- 最大承载 =LinkedBlockingQueue容量 +maximumPoolSize=5+3
package com.unsafe;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.util.concurrent.*;
public class ExecutorsPro {
public static void main(String[] args) {
// Executors 工具类 3大方法
// ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
// ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
// ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的 遇强则强
// new ThreadPoolExecutor.AbortPolicy()
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
for (int i = 1; i <= 50; i++) {
final int tmp =i;
// 使用线程池来创建线程
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok"+tmp);
});
}
//线程池用完要关闭
threadPoolExecutor.shutdown();
}
}
- 策略二 new ThreadPoolExecutor.CallerRunsPolicy()//满了就哪来回哪儿去,不抛异常
package com.unsafe;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.util.concurrent.*;
public class ExecutorsPro {
public static void main(String[] args) {
// Executors 工具类 3大方法
// ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
// ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
// ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的 遇强则强
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()//满了就哪来回哪儿去,不抛异常
);
for (int i = 1; i <= 15; i++) {
final int tmp =i;
// 使用线程池来创建线程
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok"+tmp);
});
}
//线程池用完要关闭
threadPoolExecutor.shutdown();
}
}
- 策略三:队列满了不会抛出异常,丢掉任务
package com.unsafe;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.util.concurrent.*;
public class ExecutorsPro {
public static void main(String[] args) {
// Executors 工具类 3大方法
// ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
// ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
// ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的 遇强则强
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy()//
);
for (int i = 1; i <= 9; i++) {
final int tmp =i;
// 使用线程池来创建线程
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok"+tmp);
});
}
//线程池用完要关闭
threadPoolExecutor.shutdown();
}
}
- 策略四: 队列满了,尝试和最早的竞争,如果竞争失败,则被丢弃
package com.unsafe;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.util.concurrent.*;
public class ExecutorsPro {
public static void main(String[] args) {
// Executors 工具类 3大方法
// ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
// ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
// ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的 遇强则强
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy()//
);
for (int i = 1; i <= 15; i++) {
final int tmp =i;
// 使用线程池来创建线程
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok"+tmp);
});
}
//线程池用完要关闭
threadPoolExecutor.shutdown();
}
}
扩展
i/o密集型和cpu密集型(调优)
最大线程数如何定义 线程池的最大大小如何定义
1.cpu密集型,cpu几核就是几 ,这样程序可以并行,可以保持cpu的效率最高
2.I/O密集型:
I/O一般十分耗资源,是大型任务
最大线程 > 程序中I/O密集型线程数量
两倍最佳
获取cpu的核心数
System.out.println(Runtime.getRuntime().availableProcessors()+“核心数”);