16_线程池

文章目录

  • 完整的线程状态转换图
    • 理论层面
    • 代码层面
  • 线程池
    • 3种线程池
    • 线程池的使用
  • 多线程的实现方式三:实现Callable接口
  • 单例设计模式(线程安全)

完整的线程状态转换图

理论层面

代码层面

在这里插入图片描述

线程池

提高效率

3种线程池

Executors: 线程工具类, 负责产生线程池

ExecutorServices: 代表线程池对象,负责接受线程池

  • ExecutorService newCachedThreadPool()
    • 特点:
      • 会根据需要创建新线程,也可以自动删除,60s处于空闲状态的线程
      • 线程数量可变立刻执行提交的异步任务(异步任务:在子线程中执行的任务)
  • ExecutorService newFixedThreadPool(int nThreads)
    • 特点:
      • 线程数量固定
      • 维护一个无界队列(暂存已提交的来不及执行的任务)
      • 按照任务的提交顺序,将任务执行完毕
  • ExecutorService newSingleThreadExecutor()
    • 特点:
      • 单个线程
      • 维护了一个无界队列(暂存已提交的来不及执行的任务)
      • 按照任务的提交顺序,将任务执行完毕

线程池的使用

向线程池传入

Future<?> submit(Runnable task)

Future<T> submit(Callable<T> task)

说明
Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。

eg:


public class Demo {
    public static void main(String[] args) {
        /*
        线程池的使用:
        Future<?> submit(Runnable task)
        Future<T> submit(Callable<T> task)
         */

        // 1. 创建线程池对象
        // Executors: 线程工具类, 负责产生线程池
        ExecutorService pool = Executors.newCachedThreadPool();

        // 2. 向线程池中提交任务
        pool.submit(new MyRunnableTask());
        pool.submit(new MyRunnableTask());  
        
    }
}

class MyRunnableTask implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "hello world");
    }
}

关闭线程池

shutdown()      // 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。

shutdownNow()     // 试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。

eg:


public class Demo {
    public static void main(String[] args) {
        /*
        线程池的使用:
        Future<?> submit(Runnable task)
        Future<T> submit(Callable<T> task)
         */

        // 1. 创建线程池对象
        // Executors: 线程工具类, 负责产生线程池
        ExecutorService pool = Executors.newFixedThreadPool(2);

        // 2. 向线程池中提交任务
        pool.submit(new MyRunnableTask());
        pool.submit(new MyRunnableTask());
        pool.submit(new MyRunnableTask());
        pool.submit(new MyRunnableTask());

        // 3. 关闭线程池
        pool.shutdown();

        pool.shutdownNow();

    }
}

class MyRunnableTask implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "hello world");
    }
}

向线程池中提交callable类型的任务

Future 用来存储返回值的结果(Callable是带返回值的)

  • V(表示返回值数据的类型) get() ----> 如有必要,等待计算完成,然后获取其结果。
    • 可以得到这个get()也是一个阻塞的方法

eg:


public class Demo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(2);

        // submit(Callable task)
        Future<String> future = pool.submit(new MyCallableTask());

        // 拿到返回值结果
        String s = future.get();
        System.out.println(s);
    }
}

class MyCallableTask implements Callable<String>{

    @Override
    public String call() throws Exception {

        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
        return "aaaa";
    }
}


多线程的实现方式三:实现Callable接口

不借助线程池,需要借助FutureTask

构造方法


FutureTask(Callable<V> callable)  
//  创建一个 FutureTask,一旦运行就执行给定的 Callable。

eg:


public class Demo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1. 创建FutureTask对象
        /*
        FutureTask(Callable<V> callable)
        创建一个 FutureTask,一旦运行就执行给定的 Callable。
         */
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());

        // 2. 让任务运行在线程中
        Thread t = new Thread(futureTask);
        t.start();

        // 3. 获取任务执行的结果
        String s = futureTask.get();
        System.out.println(s);
    }
}

class MyCallable implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("bbb");
        return "aaa";
    }
}


单例设计模式(线程安全)

  1. 构造方法私有
  2. 提供一个全局的自身的成员变量
  3. 提供一个静态的方法获取实例

同步方法


public class Singleton {

    //2. 提供一个全局的自身的成员变量
    private static Singleton instance;
    // 1. 构造方法私有

    private Singleton() {
    }

    //3. 提供一个静态的方法获取实例
    public  static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

双重认证

public class Singleton {

    //2. 提供一个全局的自身的成员变量
    private static Singleton instance;
    // 1. 构造方法私有

    private Singleton() {
    }

    //3. 提供一个静态的方法获取实例
    public  static Singleton getInstance() {

        // double check
        if (instance == null) {
            // 假设A线程抢到了CPU执行权 A执行
            // A持有锁对象
            // 切换B线程 B执行
            // B没有锁 进入不了sync
            synchronized (Singleton.class) {
                // A线程进来
                // B进来了
                // 第二次校验
                if (instance == null) {
                    instance = new Singleton();

                }
            }
        }
        return instance;
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/308853.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

统一网关 Gateway【微服务】

文章目录 1. 前言2. 搭建网关服务3. 路由断言工厂4. 路由过滤器4.1 普通过滤器4.2 全局过滤器4.3 过滤器执行顺序 5. 跨域问题处理 1. 前言 通过前面的学习我们知道&#xff0c;通过 Feign 就可以向指定的微服务发起 http 请求&#xff0c;完成远程调用。但是这里有一个问题&am…

【JAVA】线程的run()和start()有什么区别?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 run() 方法&#xff1a; start() 方法&#xff1a; 区别总结&#xff1a; 结语 我的其他博客 前言 多线程编程是Java中一个重要…

生成式 AI 如何重塑软件开发流程和开发工具?

生成式AI正在重塑开发流程和开发工具&#xff0c;通过自动化和优化软件开发过程&#xff0c;提高开发效率和质量。它可以帮助开发人员快速生成代码、测试和部署应用程序&#xff0c;同时减少错误和缺陷。此外&#xff0c;生成式AI还可以帮助开发人员快速理解和解决复杂的技术问…

Vulnhub靶机:Corrosion1

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;corrosion:1&#xff08;10.0.2.12&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/c…

Vue3-46-Pinia-获取全局状态变量的方式

使用说明 在 Pinia 中&#xff0c;获取状态变量的方式非常的简单 &#xff1a; 就和使用对象一样。 使用思路 &#xff1a; 1、导入Store&#xff1b;2、声明Store对象&#xff1b;3、使用对象。 在逻辑代码中使用 但是 Option Store 和 Setup Store 两种方式定义的全局状态变量…

0109作业

1> 思维导图 2> 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin&quo…

设计与实现基于Java+MySQL的模拟银行ATM操作系统

课题背景 随着现代经济的发展&#xff0c;电子支付和自动化银行服务已成为人们生活中不可或缺的一部分。自动取款机&#xff08;ATM&#xff09;作为一种常见的自助服务设备&#xff0c;使用户能够方便地进行资金的存取、查询余额、转账等操作&#xff0c;而无需到银行柜台。 …

浅淡A100-4090-性价比

大模型的训练用 4090 是不行的&#xff0c;但推理&#xff08;inference/serving&#xff09;用 4090 不仅可行&#xff0c;在性价比上还能比 H100 稍高。4090 如果极致优化&#xff0c;性价比甚至可以达到 H100 的 2 倍。 -------------------- FP64&#xff08;双精度浮点&a…

pycharm社区版配置flask开发环境

新建配置文件&#xff0c;类型选择Shell Script 设置Execute中flask.exe的路径 设置options &#xff1a;--appflask_app.py run --port5000 --debug 设置working 路径 设置环境变量FLASK_APPflask_app.py;FLASK_ENVdevelopment 注意&#xff1a;FLASK_APPflask_app.py和上…

automa插件使用的一些经验

automa&#xff0c;我承认我写不出来这样的代码&#xff0c;早年的时候公司想过做一个爬虫的工具&#xff0c;那个时候RPA还没有火&#xff0c;虽然下载也没怎么火.RPA再牛&#xff0c;还是需要工程师&#xff0c;想一点经验都没有人来做&#xff0c;还是理解不了。能够简化数据…

Java接口的解析

在 Java 中&#xff0c;接口&#xff08;Interface&#xff09;是一种抽象类型&#xff0c;用于定义一组相关方法的契约。接口只包含方法的签名&#xff0c;而没有方法的实现。实现接口的类必须提供接口中定义的方法的具体实现。 以下是对 Java 接口的解析&#xff1a; 这只是…

【uniapp】遇到的一些问题

一、小程序中textarea ios样式不生效的方法 默认有内边距&#xff0c;加个disable-default-padding"true" 二、uni-data-picker循环使用&#xff0c;一个改了全局的值 换成了uni自带的picker&#xff0c;下面括号里必须有默认值&#xff0c;为空字符串的时候&…

国产AI工具钉钉AI助理:开启个性化助手服务的新篇章

钉钉AI助理是钉钉平台的一项功能&#xff0c;它可以根据用户的需求提供个性化的AI助手服务。用户可以在AI助理页面一键创建个性化的AI助理&#xff0c;如个人的工作AI助理、旅游AI助理、资讯AI助理等。企业也可以充分使用企业所沉淀的知识库和业务数据&#xff0c;在获得授权后…

Python实现PDF—>Excel的自动批量转换(附完整代码)

Python实现PDF—>Excel的自动批量转换&#xff08;附完整代码&#xff09; 话不多说&#xff0c;先看效果&#xff01; 需要转换的PDF&#xff1a; 转换后的Excel&#xff1a; 01、底层原理 PDF 到 Excel 的转换涉及不同文件格式之间的数据提取和重构。底层原理可以简…

【GDAL】Windows下VS+GDAL开发环境搭建

Step.0 环境说明&#xff08;vs版本&#xff0c;CMake版本&#xff09; 本地的IDE环境是vs2022&#xff0c;安装的CMake版本是3.25.1。 Step.1 下载GDAL和依赖的组件 编译gdal之前需要安装gdal依赖的组件&#xff0c;gdal所依赖的组件可以在官网文档找到&#xff0c;可以根据…

白嫖aws创建Joplin server服务器

网上有很多的Joplin服务器的搭建教程&#xff0c;但是基本都是抄来抄去&#xff0c;对初学者实在是太不友好了。 话不多说&#xff0c;说干就干&#xff0c;自己从头找资料搭了一个&#xff0c;这可能是全网最好的Joplin服务器搭建教程了。 aws服务器 aws的服务器还是很香的&…

idea git回滚之前提交记录

提交代码时&#xff0c;如果不小心提交了不需要提交的内容&#xff0c;在本地仓库中&#xff0c;此时需要回滚版本&#xff0c;如何回滚 1.打开git控制台&#xff0c;左下角git,选择要处理的分支&#xff0c;选择刷新获取最新git提交记录 2&#xff09;选中自己commit需要回滚…

Fluids —— Minimal fluid setups

目录 Waterline FLIP Boundary Boundary flow 创建流体设置的三个基本方法&#xff1b; Waterline 由FLIP Container SOP与FLIP Solver SOP组成的基本network&#xff0c;可不需要任何外部源&#xff1b; FLIP Container SOP&#xff0c;能使用不同的容器形状&#xff1b;F…

PiflowX-MysqlCdc组件

MysqlCdc组件 组件说明 MySQL CDC连接器允许从MySQL数据库读取快照数据和增量数据。 计算引擎 flink 组件分组 cdc 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默认值允许值是否必填描述例子hostnameHostname“”无是MySQL…

MySql -数据库基本概念

一、数据库的基本概念 1.为什么要学数据库&#xff1f; 之前我们如果想将一些数据实现永久化存储&#xff0c;可以怎么做呢&#xff1f;没错。使用IO流的技术将数据保存到本地文件中但是接下来我有这样一个需求&#xff1a;将下面的user.txt文件中的王五年龄修改为35 张三 2…