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个线程。会出现线程复用的情况

image

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();
		}

	}
}
可以看到 循环了多少次 就创建了多少个线程

image

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个线程,单个线程的线程池

image

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后执行

image

posted @ 2025-07-17 15:14  skystrivegao  阅读(11)  评论(0)    收藏  举报