JUC学习-19-浅谈线程池相关
JUC学习-19-浅谈线程池相关
一、定义:
我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程是需要时间。
那么有没有一种办法是得线程可以重复利用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?
线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁的创建线程对象的操作,无需反复创建线程而消耗过多的资源。
二、线程池的优势:
线程池做的工作主要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。
三、主要特点为:
线程复用;控制最大并发数;管理线程。
第一:降低资源消耗。通过重复利用已经创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度,任务可以不需要等待线程创建就能立即执行。
第三:提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性。使用线程吃可以进行统一的分配,调优和监控。
四、线程池的使用:
Java里面线程池的顶级接口是 java.util.concurrent.Executor,但是严格意义上讲,Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是java.util.concurrent.ExecutorService。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在java.util.concurrent.Executors线程工厂类里面提供了一些静态工厂,生成一些常用的线程池。官方建议使用Executors工程类来创建线程池对象。Java类库提供了许多静态方法来拆功能键一个线程池:
Executors类中创建线程池的方法如下:
1. newFixedThreadPool 创建一个固定长度的线程池,当达到线程最大数量时】线程池的规模将不再变化。
public class ThreadPoolTest {
public static void main(String[] args) {
class Task implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "\t办理业务");
}
}
Task task = new Task();
ExecutorService threadPool = Executors.newFixedThreadPool(5);
try {
for (int i = 1; i <= 10; i++) {
threadPool.execute(task);
}
} catch (Exception e) {
} finally {
threadPool.shutdown();
}
}
}
可以看到 最多创建5个线程。会出现线程复用的情况
2. newCachedThreadPool 创建一个可缓存的线程池,如果当前线程池的规模超出了处理需求,将回收空的线程;当需求增加时,会增加线程数量;线程池规模无限制
public class ThreadPoolTest {
public static void main(String[] args) {
class Task implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "\t办理业务");
}
}
Task task = new Task();
// 固定大小线程池
// ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 单个线程线程池
//ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 动态扩容创建线程 线程池
ExecutorService threadPool = Executors.newCachedThreadPool();
try {
for (int i = 1; i <= 10; i++) {
threadPool.execute(task);
}
} catch (Exception e) {
} finally {
threadPool.shutdown();
}
}
}
可以看到 循环了多少次 就创建了多少个线程
3. newSingleThreadPoolExecutor创建一个单线程的Executor,确保任务对了,串行执行
public class ThreadPoolTest {
public static void main(String[] args) {
class Task implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "\t办理业务");
}
}
Task task = new Task();
// ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 单个线程
ExecutorService threadPool = Executors.newSingleThreadExecutor();
try {
for (int i = 1; i <= 10; i++) {
threadPool.execute(task);
}
} catch (Exception e) {
} finally {
threadPool.shutdown();
}
}
}
可以看到 就创建1个线程,单个线程的线程池
4. newScheduledThreadPool 定时调度
public class ThreadPoolTest {
public static void main(String[] args) {
class Task implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "\t办理业务");
}
}
Task task = new Task();
// 固定大小线程池
// ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 单个线程线程池
//ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 动态扩容创建线程 线程池
// ExecutorService threadPool = Executors.newCachedThreadPool();
// 定时执行 线程池
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
try {
for (int i = 1; i <= 10; i++) {
// threadPool.execute(task);
threadPool.schedule(task, 5, TimeUnit.SECONDS);
}
} catch (Exception e) {
} finally {
threadPool.shutdown();
}
}
}
延迟5s后执行
本文来自博客园,作者:skystrivegao,转载请注明原文链接:https://www.cnblogs.com/skystrive/p/18986846
整理不易,如果对您有所帮助 请点赞收藏,谢谢~