Java 线程池

Java 线程池

线程池(懒汉模式)

管理线程的一套解决方案,主要作用:

  1. 控制线程数量
    线程数量过多会导致过多的资源消耗,并且会导致CPU过度切换降低整体并发性能
  2. 重用线程
    线程不应当随着任务的声明周期一致,频繁的创建和销毁线程也会给系统带来额外的开销
	// 创建固定大小的线程池
	ExcutorService threadPool = Executors.newFixedThreadPool(int num);	// 创建线程池内最大num个线程同时执行
	
	// 创建线程
	// 开始全部将线程加入线程池 
	// 执行num个线程同时执行
	for(int i=0;i<5;i++){
		Runnable r = new Runnable(){
			public void run(){
				try{
					Thread t = Thread.currentThread();
					System.out.println(t.getName());
					Thread.sleep(5000);
					System.out.println(t.getName());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		threadPool.execute(r);
	}
	
	threadPool.shutdown();			// -> 所有线程执行完成停止线程池
	threadPool.shutdownNow();		// -> 线程池立刻停止
### Java线程池的使用与实现 Java线程池是一种高效的并发编程工具,用于管理线程生命周期并减少线程创建和销毁的开销[^1]。通过复用线程线程池可以显著提高系统的性能和资源利用率。 #### Java线程池的核心组件 Java线程池主要由以下核心组件构成: - **核心线程数(corePoolSize)**:线程池中保持的最小线程数,即使这些线程处于空闲状态。 - **最大线程数(maximumPoolSize)**:线程池中允许的最大线程数。 - **任务队列(workQueue)**:用于保存等待执行任务的队列。 - **线程工厂(ThreadFactory)**:用于创建新线程的对象。 - **拒绝策略(RejectedExecutionHandler)**:当线程池无法处理新任务时的处理策略。 #### 创建线程池的方式 在Java中,可以通过`ThreadPoolExecutor`类来手动创建线程池,或者使用`Executors`工具类提供的静态方法来快速创建不同类型的线程池。 ##### 使用`ThreadPoolExecutor`创建线程池 以下是一个自定义线程池的示例代码: ```java import java.util.concurrent.*; public class CustomThreadPool { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 10, // 核心线程数 25, // 最大线程数 10L, // 空闲线程存活时间 TimeUnit.SECONDS, // 时间单位 new LinkedBlockingDeque<>(), // 任务队列 new CustomThreadFactory(), // 自定义线程工厂 new ThreadPoolExecutor.AbortPolicy() // 拒绝策略 ); // 提交任务到线程池 for (int i = 0; i < 30; i++) { threadPoolExecutor.execute(() -> { System.out.println(Thread.currentThread().getName() + " is running."); }); } // 关闭线程池 threadPoolExecutor.shutdown(); } } class CustomThreadFactory implements ThreadFactory { private final AtomicInteger counter = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("自定义线程-" + counter.getAndIncrement()); return thread; } } ``` ##### 使用`Executors`创建线程池 `Executors`工具类提供了多种便捷方法来创建不同类型的线程池: - `newFixedThreadPool(int nThreads)`:创建一个固定大小的线程池。 - `newCachedThreadPool()`:创建一个可根据需要调整大小的线程池。 - `newSingleThreadExecutor()`:创建一个单线程线程池。 - `newScheduledThreadPool(int corePoolSize)`:创建一个支持定时及周期性任务执行的线程池。 #### `execute`与`submit`的区别 `execute`和`submit`是提交任务到线程池的两种方法,它们的主要区别在于返回值和异常处理方式: - `execute(Runnable command)`:仅接受`Runnable`类型的任务,不返回结果,且不会抛出异常[^2]。 - `submit(Callable<T> task)`或`submit(Runnable task)`:可以接受`Runnable`或`Callable`类型的任务,返回一个`Future`对象,用于获取任务执行结果或检查任务状态[^2]。 #### 线程池的最佳实践 - **合理设置线程池大小**:根据硬件资源和任务特性设置合适的线程池大小,避免过载或资源浪费。 - **选择合适的任务队列**:根据任务的优先级和数量选择适当的队列类型,如`LinkedBlockingQueue`或`ArrayBlockingQueue`。 - **定义明确的拒绝策略**:根据业务需求选择合适的拒绝策略,如`AbortPolicy`、`CallerRunsPolicy`等。 - **及时关闭线程池**:在不再需要线程池时调用`shutdown()`方法,确保线程池中的资源被正确释放。 #### 示例代码:使用`submit`方法 以下是一个使用`submit`方法的示例代码: ```java import java.util.concurrent.*; public class SubmitExample { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<Integer> future = executorService.submit(() -> { Thread.sleep(2000); return 42; }); System.out.println("任务正在执行..."); System.out.println("任务结果:" + future.get()); executorService.shutdown(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值