java之线程池

线程池:三大方法、七大参数、四种拒绝策略

池化技术

程序的运行,本质:占用系统的资源!优化资源的使用!=> 池化技术

线程池、连接池、内存池、对象池///… 创建、销毁十分浪费资源

池化技术: 事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我

线程池的好处:

1、降低资源的消耗

2、提高相应的速度

3、方便管理

线程复用、可以控制最大并发数、管理线程

线程池:三大方法

java之线程池_多线程

ExecutorService threadExecutor = Executors.newSingleThreadExecutor();// 单个线程
Executors.newFixedThreadPool(5); // 固定大小的线程池
ExecutorService threadExecutor = Executors.newCachedThreadPool(); // 可伸缩的线程池

//Executors 工具类 3大方法
//使用了线程池之后要使用线程池创建线程
public class Demo01 {

public static void main(String[] args) {
// ExecutorService service = Executors.newSingleThreadExecutor();//单个线程
// ExecutorService service = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
ExecutorService service = Executors.newCachedThreadPool();//可伸缩的,
try {
for (int i = 0; i < 10; i++) {
service.execute(() -> {
System.out.println(Thread.currentThread().getName() + "ok");
});
}
//线程池用完要关闭线程池
} finally {
service.shutdown();
}
}
}

线程池:七大参数

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

// 三大方法本质ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小 一直开着
int maximumPoolSize, // 最大线程池大小
long keepAliveTime, // 超时了没有人调用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂;创建线程的,一般不动
RejectedExecutionHandler handler) { // 拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

java之线程池_线程池_02

手动创建线程池

public class testThreadPoolExecutor {
public static void main(String[] args) {
ExecutorService threadPoolExecutor = new ThreadPoolExecutor(
2,//核心线程数
4,//最大线程数
3,//多久没调用就释放池
TimeUnit.SECONDS,//超时单位
new ArrayBlockingQueue<>(6),//阻塞队列大小
Executors.defaultThreadFactory(), // 线程工厂,创建线程的,默认不用改
//队列满了,线程池满了,还有其他任务过来时拒绝策略
// new ThreadPoolExecutor.AbortPolicy()//满了,不处理,抛出异常
// new ThreadPoolExecutor.CallerRunsPolicy()//由调用线程(提交任务的线程)处理该任务
// new ThreadPoolExecutor.DiscardPolicy()//满了,丢掉任务,不抛出异常
new ThreadPoolExecutor.DiscardOldestPolicy()//抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务
);

try {
// 最大承载:Deque + max 等待队列容量和最大线程数之和
// 超过 RejectedExecutionException 抛不抛出异常看拒绝策略
for (int i = 0; i <12; i++) {
// 使用了线程池之后,使用线程池来创建线程
threadPoolExecutor.execute(() -> {
System.out.println(Thread.currentThread().getName() + "run");
});
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPoolExecutor.shutdown();
}

}
}
线程池:四种拒绝策略

java之线程池_线程池_03

/*
* new ThreadPoolExecutor.AbortPolicy() // 银行满了 还有人进来,不处理这个人,抛出异常
* new ThreadPoolExecutor.CallerRunsPolicy() // 哪来的去哪里,下面的线程就是main执行了多出来的一个人
* new ThreadPoolExecutor.DiscardPolicy() // 不抛出异常,银行满了,丢点任务
* new ThreadPoolExecutor.DiscardOldestPolicy() // 银行满了,试探最早的是否结束,如果结束就跟进,没结束就不处理,不抛出异常。不是插队
* */
public class Demo02 {
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
// new ThreadPoolExecutor.AbortPolicy() // 银行满了 还有人进来,不处理这个人,抛出异常
// new ThreadPoolExecutor.CallerRunsPolicy() // 哪来的去哪里,下面的线程就是main执行了多出来的一个人
// new ThreadPoolExecutor.DiscardPolicy() // 不抛出异常,银行满了,丢点任务
new ThreadPoolExecutor.DiscardOldestPolicy() // 银行满了,试探最早的是否结束,如果结束就跟进,没结束就不处理,不抛出异常。不是插队
);
try {
// 最大承载 que + max 窗口+等待席
// 超出 RejectedExecutionException
for (int i = 1; i <= 9; i++) {
// 使用了线程池之后,使用线程池来创建线程
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+" ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
}
}

小结和扩展

最大线程如何定义

1、CPU密集型 几核,就是几,可以保持CPU的效率最高 线程 CPU密集型是

​ ​​System.out.println(Runtime.getRuntime().availableProcessors());​​ 输出核数量

2、IO密集型 > 判断程序中十分耗IO的线程 一般两倍

程序 1个大型任务 io十分占内存

public class Demo03 {
public static void main(String[] args) {
// 最大线程到底该如何定义
// 1、CPU 密集型,几核,就是几,可以保持CPu的效率最高!
// 2、IO 密集型 > 判断你程序中十分耗IO的线程,
// 程序 15个大型任务 io十分占用资源!

// 获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());

// 自定义线程池!工作 ThreadPoolExecutor
ExecutorService threadPoolExecutor = new ThreadPoolExecutor(
2,
Runtime.getRuntime().availableProcessors() ,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
//队列满了,尝试去和 早的竞争,也不会抛出异常!
new ThreadPoolExecutor.DiscardOldestPolicy()

);

try {
// 大承载:Deque + max
// 超过 RejectedExecutionException
for (int i = 1; i <= 9; i++) {
// 使用了线程池之后,使用线程池来创建线程
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+" ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPoolExecutor.shutdown();
}

}
}

java之线程池_多线程_04