
为什么需要线程池

java中为了提高并发度,可以使用多线程共同执行,但是如果有大量线程短时间之内被创建和销毁,会占用大量的系统时间,影响系统效率。
为了解决上面的问题,java中引入了线程池,可以使创建好的线程在指定的时间内由系统统一管理,而不是在执行时创建,执行后就销毁,从而避免了频繁创建、销毁线程带来的系统开销。
创建线程池的方式
创建线程池的方式有 7 种:
1.newFixedThreadPool
创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待。
代码示例如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTest extends Thread {
private int index;
public MyExecutor(int i) {
this.index = i;
}
public void run() {
try {
System.out.println("[" + this.index + "] start....");
Thread.sleep((int) (Math.random() * 10000));
System.out.println("[" + this.index + "] end.");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
ExecutorService service = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
service.execute(new MyExecutor(i));
// service.submit(new MyExecutor(i));
}
System.out.println("submit finish");
service.shutdown();
}
}
2.newCachedThreadPool
创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程。
代码示例如下:
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
final int j=i;
executorService.submit(()->{
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+j);
});
}
System.out.println(executorService);
}
3.newSingleThreadExecutor
创建单个线程数的线程池,它可以保证先进先出的执行顺序。
代码示例如下:
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 6; i++) {
final int j=i;
executorService.execute(()->{
System.out.println(Thread.currentThread().getName()+" "+j);
});
}
executorService.shutdown();
}
4.newScheduledThreadPool
创建一个可以执行延迟任务的线程池,延迟执行。
代码示例如下:
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(int corePoolSize);
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
log.warn("schedule run");
}
}, 3, TimeUnit.SECONDS);
}
5.newSingleThreadScheduledExecutor
创建一个单线程的可以执行延迟任务的线程池。
代码示例如下:
public static void main(String[] args) throws Exception {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
// 1秒打印一次 当前线程名
service.scheduleAtFixedRate(() -> System.out.println(Thread.currentThread().getName()), 1, 1, TimeUnit.SECONDS);
// 主线程等待10秒
TimeUnit.SECONDS.sleep(10);
System.out.println("主线程退出了");
}
输出:
pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 主程序退出了 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1
6.newWorkStealingPool
创建一个抢占式执行的线程池(任务执行顺序不确定)【JDK 1.8 添加】。
代码示例如下:
public static void main(final String[] arguments) throws InterruptedException {
ExecutorService excr = Executors.newWorkStealingPool();
ThreadPoolExecutor mypool = (ThreadPoolExecutor) Executors.newCachedThreadPool();;
System.out.println("size of mypool:" + mypool.getPoolSize());
excr.submit(new Threadimpl());
excr.submit(new Threadimpl());
System.out.println("Total number threads scheduled):"+ mypool.getTaskCount());
excr.shutdown();
}
static class Threadimpl implements Runnable {
public void run() {
try {
Long num = (long) (Math.random() / 30);
System.out.println("Thread Name:" +Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(num);
System.out.println("after sleep Thread Name:" +Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
7.ThreadPoolExecutor
最原始的创建线程池的方式,它包含了 7 个参数可供设置。
代码示例如下:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExecutorDemo {
private static final int CORE_POOL_SIZE = 5;
private static final int MAX_POOL_SIZE = 10;
private static final int QUEUE_CAPACITY = 100;
private static final Long KEEP_ALIVE_TIME = 1L;
public static void main(String[] args) {
//使用阿里巴巴推荐的创建线程池的方式
//通过ThreadPoolExecutor构造函数自定义参数创建
ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),
new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 10; i++) {
//创建WorkerThread对象(WorkerThread类实现了Runnable 接口)
Runnable worker = new MyRunnable("" + i);
//执行Runnable
executor.execute(worker);
}
//终止线程池
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
mikechen睿哥
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。