文章目录
思维导图:
https://naotu.baidu.com/file/89fb28b05e3395800f9dc2d332d2b198?token=9b45e08e55281667
1线程池的介绍
1.1 一个线程
public class EveryTaskOneThread {
public static void main(String[] args) {
Thread thread = new Thread(new Task());
thread.start();
}
static class Task implements Runnable {
@Override
public void run() {
System.out.println("执行了任务");
}
}
}
1.2 for循环创建线程
public class ForLoop {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
Thread thread = new Thread(new Task());
thread.start();
}
}
static class Task implements Runnable {
@Override
public void run() {
System.out.println("执行了任务");
}
}
}
2创建和停止线程池
2.1线程池构造函数的参数
2.1.1 corePoolSize 和maxPoolSize
1》假如 core pool size 的容量是5个,是核心处理线程。 当用完以后又有一些线程过来,他会放到存储队列中(假如是10)。对列中就是存放任务的。当核心线程有的处理完列,就会从队列中拿一个,拿一个。
2》 当容量和队列都满列,就会增加新的线程。最多能扩展到最大线程数
即:
2.1.2线程规则
2.1.3keepAliveTime
光突破不回收也不行。核心就那么多,当不忙的时候要把线程回收回来。
2.1.4threadFactory
2.1.4工作队列
直接队列: 做一些简单中转。本身是没有容量的。存不下任务。 注意将最大队列设置的大一点 ,因为没有队列作为缓冲啦。
无界队列: 无限大。可防止流量突增(流量处理不完,就放在队列中)。他有风险,他处理任务的速度跟不上提交的速度。就会造成队列的浪费或者oa 溢出。
有界队列:此时maxpoolsize就有意义啦。
2.2线程池应该手动创建还是自动创建
手动创建更好。
2.2.1 newFixedThreadPool演示内存溢出
2.2.1.1演示newFixedThreadPool:
package threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 描述: 演示newFixedThreadPool
*/
public class FixedThreadPoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 1000; i++) {
executorService.execute(new Task());
}
}
}
class Task implements Runnable {
@Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
2.2.1.2 演示newFixedThreadPool出错的情况:
设值 睡眠时间过长,导致任务执行不完,对列越来越多。最后导致内存不足
可以设置的内存小一点‘:
package threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 描述: 演示newFixedThreadPool出错的情况
*/
public class FixedThreadPoolOOM {
private static ExecutorService executorService = Executors.newFixedThreadPool(1);
public static void main(String[] args) {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
executorService.execute(new SubThread());
}
}
}
class SubThread implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
报错:
2.2.2 newSingleThreadExecutor
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 1000; i++) {
executorService.execute(new Task());
}
}
}
2.2.3 CachedThreadPool
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
executorService.execute(new Task());
}
}
}
2.2.4 ScheduledThreadPoolTest
public class ScheduledThreadPoolTest {
public static void main(String[] args) {
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10);
// threadPool.schedule(new Task(), 5, TimeUnit.SECONDS);
threadPool.scheduleAtFixedRate(new Task(), 1, 3, TimeUnit.SECONDS);
}
}
2.2.5总结
2.3线程池里的线程数量设定为多少比较合适
2.4常见线程池的特点和用法
2.5停止线程池的正确方法:
package threadpool;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 描述: 演示关闭线程池
*/
public class ShutDown {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executorService.execute(new ShutDownTask());
}
Thread.sleep(1500);
// List<Runnable> runnableList = executorService.shutdownNow();
executorService.shutdown();
executorService.execute(new ShutDownTask());
// boolean b = executorService.awaitTermination(7L, TimeUnit.SECONDS);
// System.out.println(b);
// System.out.println(executorService.isShutdown());
// executorService.shutdown();
// System.out.println(executorService.isShutdown());
// System.out.println(executorService.isTerminated());
// Thread.sleep(10000);
// System.out.println(executorService.isTerminated());
// executorService.execute(new ShutDownTask());
}
}
class ShutDownTask implements Runnable {
@Override
public void run() {
try {
Thread.sleep(500);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "被中断了");
}
}
}
2.6任务太多,怎么拒绝?
钩子方法,给线程池加点料
实现原理,源码分析
使用线程池注意的点