线程池~~

线程使用存在的问题

  • 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
  • 如果大量线程在执行,会涉及到线程间上下文的切换,会极大的消耗CPU运算资源。

解决办法:

使用线程池技术指定创建的线程数量,去执行无限的任务

什么是线程池?

就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。

线程池怎么使用?

线程池使用大致流程:

1.创建线程池指定线程开启的数量

2.提交任务给线程池,线程池中的线程就会获取任务,进行处理任务。

3.线程处理完任务,不会销毁,而是返回到线程池中,等待下一个任务执行。

4.如果线程池中的所有线程都被占用,提交的任务,只能等待线程池中的线程处理完当前任务。

线程池处理Runnable任务

线程池API的学习

java 复制代码
java.util.concurrent.ExecutorService 是线程池接口类型。
使用时我们不需自己实现,JDK已经帮我们实现好了。
获取线程池我们使用工具类java.util.concurrent.Executors的静态方:
        public static ExecutorService newFixedThreadPool (int num) 
        指定线程池最大线程池数量获取线程池

线程池ExecutorService的相关方法:
提交执行任务方法:
<T> Future<T>  submit(Callable<T> task) 
Future<?> submit(Runnable task)
关闭线程池方法(一般不使用关闭方法,除非后期不用或者很长时间都不用,就可以关闭)
void shutdown()  启动一次顺序关闭,执行以前提交的任务,但不接受新任务。 

线程池处理Runnable任务的大致步骤是怎样的?

1.指定线程数量获取线程池

2.定义Runnable任务类型

3.创建任务对象,提交给线程池

java 复制代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class StudentTask implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"在教授学员游泳");
    }
}
public class Test {
    public static void main(String[] args) {
        //创建线程池对象(指定初始化的线程数量)
        ExecutorService es = Executors.newFixedThreadPool(3);
        //把线程任务,交给线程池执行
        es.submit(new StudentTask());
        es.submit(new StudentTask());
        es.submit(new StudentTask());
        es.submit(new StudentTask());

    }
}

运行结果:
pool-1-thread-1在教授学员游泳
pool-1-thread-3在教授学员游泳
pool-1-thread-2在教授学员游泳
pool-1-thread-1在教授学员游泳

线程池处理Callable任务

Callable接口概述

java 复制代码
public interface Callable<V> {
    V call() throws Exception;
}

public interface Runnable{
    void run();
}
java 复制代码
<T> Future<T>  submit(Callable<T> task)  提交Callable任务方法
返回值类型Future的作用就是为了获取任务执行的结果。
Future是一个接口,里面存在一个get方法用来获取值。

Callable任务处理使用步骤

1.创建线程池

2.定义Callable任务

3.创建Callable任务,提交任务给线程池

4.获取执行结果

java 复制代码
import java.util.concurrent.*;

public class Test1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建线程池对象
        ExecutorService es = Executors.newFixedThreadPool(10);
        //创建Callable类型的线程任务
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(1000);
                int sum = 0;
                for (int i = 0; i < 10; i++) {
                    sum += i;
                }
                return sum;
            }
        };
        //把线程任务提交给线程池执行
        Future<Integer> future = es.submit(task);
        System.out.println("计算结果:"+ future.get());//计算结果:45
    }
}

Callable任务和Runnable任务相比最大的特点是什么?

可以将任务结果返回

Callable与Runnable的不同点:

1.Callable支持结果返回,Runnable不行

2.Callable可以 抛出异常,Runnable不行

线程池的好处?

  • **降低资源消耗。**减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
  • **提高响应速度。**当任务到达时,任务可以不需要等待线程创建 , 就能立即执行。
  • **提高线程的可管理性。**可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存 , 服务器死机(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。
相关推荐
Highcharts.js3 小时前
教程:基于 React + Highcharts 构建一个单页应用程序、按需数据拉取与图表渲染
开发语言·前端·数据结构·react.js·前端框架·highcharts·页面应用
头发还在的女程序员4 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats5 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
我命由我123455 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
爱写代码的小朋友6 小时前
从零开始学 Win32 API:C++ 窗口编程实战(VS Code + MinGW-w64 命令行详解)
开发语言·c++
果汁华6 小时前
Function Calling 与 Python 实战完整指南
开发语言·网络·python
小小晓.7 小时前
C++:语句和作用域
开发语言·c++
都叫我大帅哥7 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.8 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
海天鹰9 小时前
PHP上传文件
android·开发语言·php