Executor
new Thread
的弊端new Thread
新建对象,性能差;OOM
(out of memory
内存溢出),这种问题的原因不是因为单纯的new
一个Thread
,而是可能因为程序的bug或者设计上的缺陷导致不断new Thread
造成的。new Thread
去创建线程,从而减少不必要的麻烦和困扰;ThreadPoolExecutor
)的核心类ThreadPoolExecutor
一共有七个参数,这七个参数配合起来,构成了线程池强大的功能。corePoolSize
:核心线程数量;maximumPoolSize
:线程最大线程数;workQueue
:阻塞队列,存储等待执行的任务,很重要,会对线程池运行过程产生重大影响;keepAliveTime
:线程没有任务执行时最多保持多久时间终止(当线程中的线程数量大于corePoolSize
的时候,如果这时没有新的任务提交核心线程外的线程不会立即销毁,而是等待,直到超过keepAliveTime
);unit
:keepAliveTime
的时间单位;threadFactory
:线程工厂,用来创建线程,有一个默认的工场来创建线程,这样新创建出来的线程有相同的优先级,是非守护线程、设置好了名称);rejectHandler
:当拒绝处理任务时(阻塞队列满)的策略(AbortPolicy
默认策略直接抛出异常、CallerRunsPolicy
用调用者所在的线程执行任务、DiscardOldestPolicy
丢弃队列中最靠前的任务并执行当前任务、DiscardPolicy
直接丢弃当前任务)corePoolSize
、maximumPoolSize
、workQueue
三者关系 如果运行的线程数小于corePoolSize
的时候,直接创建新线程来处理任务。即使线程池中的其他线程是空闲的。如果运行中的线程数大于corePoolSize
且小于maximumPoolSize
时,那么只有当workQueue
满的时候才创建新的线程去处理任务。如果corePoolSize
与maximumPoolSize
是相同的,那么创建的线程池大小是固定的。这时有新任务提交,当workQueue
未满时,就把请求放入workQueue
中。等待空线程从workQueue
取出任务。如果workQueue
此时也满了,那么就使用另外的拒绝策略参数去执行拒绝策略。
ThreadPoolExecutor
的主要方法execute()
:提交任务,交给线程池执行;submit()
:提交任务,能够返回执行结果 execute+Future
;shutdown()
:关闭线程池,等待任务都执行完;shutdownNow()
:关闭线程池,不等待任务执行完;getTaskCount()
:线程池已执行和未执行的任务总数;getCompleteTaskCount()
:已完成的任务数量;getPoolSize()
:线程池当前的线程数量;getActiveCount()
:当前线程池中正在执行任务的线程数量;Executor
创建线程池ExecutorService
中只提供了基本的线程池的方法:submit()
、 shutdown()
、shutdownNow()
等;而不支持其他监控方法,如getTaskCount()
、getCompleteTaskCount()
等;Executors.newCachedThreadPool()
方法创建线程池Executors.newCachedThreadPool()
其目的是创建一个可缓存的线程池,如果线程池的长度超过了处理的需要,可以灵活回收空闲线程。如果没有可回收的就新建线程。newCachedThreadPool
源码如下所示:public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
Executors
中的newCachedThreadPool()
方法创建线程池,其内部实际还是通过ThreadPoolExecutor
来创建线程池,只不过很多参数都已经被指定好了。@Slf4j
public class ThreadPoolExample1 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
log.info("task:{}", index);
}
});
}
executorService.shutdown();
}
}
执行结果:
16:12:57.979 [pool-1-thread-9] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:8
16:12:57.985 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:0
16:12:57.979 [pool-1-thread-2] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:1
16:12:57.980 [pool-1-thread-4] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:3
16:12:57.980 [pool-1-thread-10] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:9
16:12:57.980 [pool-1-thread-3] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:2
16:12:57.980 [pool-1-thread-6] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:5
16:12:57.979 [pool-1-thread-5] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:4
16:12:57.980 [pool-1-thread-8] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:7
16:12:57.980 [pool-1-thread-7] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample1 - task:6
Process finished with exit code 0
Executors.newFixedThreadPool()
方法创建线程池public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
@Slf4j
public class ThreadPoolExample2 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
log.info("task:{}", index);
}
});
}
executorService.shutdown();
}
}
执行结果同上;
Executors.newSingleThreadExecutor()
方法创建线程池//源码
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
@Slf4j
public class ThreadPoolExample3 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
log.info("task:{}", index);
}
});
}
executorService.shutdown();
}
}
执行结果如下:
16:34:57.825 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:0
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:1
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:2
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:3
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:4
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:5
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:6
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:7
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:8
16:34:57.832 [pool-1-thread-1] INFO com.mmall.concurrency.example.threadPool.ThreadPoolExample3 - task:9
Process finished with exit code 0
执行得到结果与预期得到一致,线程按照顺序依次执行;
Executors.newScheduledThreadPool()
方法创建线程池public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,//此处super指的是ThreadPoolExecutor
new DelayedWorkQueue());
}
@Slf4j
public class ThreadPoolExample4 {
public static void main(String[] args) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
// executorService.schedule(new Runnable() {
// @Override
// public void run() {
// log.warn("schedule run");
// }
// }, 3, TimeUnit.SECONDS);
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
log.warn("schedule run");
}
}, 1, 3, TimeUnit.SECONDS);
// executorService.shutdown();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
log.warn("timer run");
}
}, new Date(), 5 * 1000);
}
}
如有帮助,烦请点赞收藏一下啦 (◕ᴗ◕✿)