Java多线程(三)——线程池及定时器

news2025/1/16 15:45:38

线程池就是一个可以复用线程的技术。前面三种多线程方法就是在用户发起一个线程请求就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。线程池就相当于预先创建好几个线程(招聘几个打工人),来分配之后要处理的任务(干活)

线程池的接口:ExecutorService

线程池对象

  1. 使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象

可以看到有7个参数,通过这些参数设置线程池的规模和特征。ExecutorService的常用方法有execute、submit、shutdown、shutdownNow。

  1. ThreadPoolExecutor构造器的参数:

  1. 1:指定线程池的线程数量(核心线程): corePoolSize

  1. 2:指定线程池可支持的最大线程数: maximumPoolSize

  1. 3:指定临时线程的最大存活时间: keepAliveTime

  1. 4:指定存活时间的单位(秒、分、时、天): unit

  1. 5:指定任务队列: workQueue

  1. 6:指定用哪个线程工厂创建线程: threadFactory

  1. 7:指定线程忙,任务满的时候,新任务来了怎么办: handler,默认丢弃任务并抛出RejectedExecutionException异常。

  1. ThreadPoolExecutor创建线程池对象

ExecutorService pool=new ThreadPoolExecutor(3,6,8, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(6), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
  1. 线程池处理Runnable任务 ——pool.execute()

首先实现Runnable接口,重写run方法。然后创建MyRunnable任务对象,只不过这里不是把MyRunnable任务对象交给Thread处理,而是使用线程池pool的execute()方法。

class myRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " ——>" + i);
        }
        try {
            System.out.println(Thread.currentThread().getName() + " —— 休眠");
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getName() + " —— 启动");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
//
        Runnable target=new myRunnable();
        pool.execute(target);
  1. 线程池处理Callable任务 ——pool.submit()

定义类实现Callable接口,重写call方法,封装要做的事情。然后把Callable对象进行submit(),并且可以返回执行后的结果。

class myCallable implements Callable<String> {
    private int n;
    public myCallable(int n) {
        this.n = n;
    }
    @Override
    public String call() throws Exception {
        int s=0;
        for (int i = 0; i < n; i++) {
            s+=n;
        }
        return Thread.currentThread().getName()+" 1+...+" + n +
                ", 子线程执行结果: "+s;
    }
}
//
        Callable myCallable=new myCallable(10);
        Future<String> f1 = pool.submit(myCallable);
        System.out.println(f1.get());
  1. 使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象

Executors的底层其实也是基于线程池的实现类ThreadPoolExecutor创建线程池对象的。Executors得到线程池对象的常用方法:

方法

说明

弊端

public static ExecutorService newCachedThreadPool()

线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了一段时间则会被回收掉。

允许创建的线程数量最大上限是Integer.MAX_VALUE,非常非常大

可能会创建大量线程,出现OOM错误( 内存溢出 java.lang.OutOfMemoryError )

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。

允许请求的任务队列长度是Integer.MAX_VALUE,可能会堆积大量请求,出现OOM错误

public static ExecutorService newSingleThreadExecutor ()

创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。

允许请求的任务队列长度是Integer.MAX_VALUE,可能会堆积大量请求,出现OOM错误

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。

允许创建的线程数量最大上限是Integer.MAX_VALUE,

可能会创建大量线程,出现OOM错误

Executors不适合做大型互联网场景的线程池方案,建议使用ThreadPoolExecutor来指定线程池参数,这样可以明确线程池的运行规则,规避资源耗尽的风险。

  1. 定时器

定时器是一种控制任务延时调用,或者周期调用的技术。定时器的实现方式有两种:

方式一:Timer。创建Timer定时器对象,然后开启定时器。这是一种单线程方法,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入。可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。

    Timer t=new Timer();
    t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("定时器~");
            }
        },3000,3000);

方式二: ScheduledExecutorService定时器。基于线程池,某个任务的执行情况不会影响其他定时任务的执行。先得到线程池对象,然后再进行周期调度方法。

        ScheduledExecutorService pool=Executors.newScheduledThreadPool(3);
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println("定时器");
            }
        },3,3,TimeUnit.SECONDS);
  1. 并发与并行

CPU同时可以处理线程的数量有限,所以CPU会轮询为每个线程服务,只是由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,其实可能只是并发。所以说多个线程其实是并发与并行同时进行的

  1. 线程的6种状态

NEW(新建)

线程刚被创建,但是并未启动。

Runnable(可运行)

线程已经调用了start()等待CPU调度。

Blocked(锁阻塞)

线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态。

Waiting(无限等待)

一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒。

Timed Waiting(计时等待)

同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。带有超时参数的常用方法有Thread.sleep 、Object.wait。

Teminated(被终止)

因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

concrt140.dll丢失四种方法解决丨提示游戏里找不到concrt140.dll?

电脑提示concrt140.dll文件丢失怎么办&#xff1f;由于找不到concrt140.dll&#xff0c;无法继续执行代码&#xff1f; 我们平时在打开 Adobe 应用程序、Halo、Forza Horizon 5 地平线5 等时&#xff0c;可能会遇到找不到 concrt140.dll。因此&#xff0c;这不是特定于某个应用…

基频的后处理

基频归一化 基频为什么要归一化&#xff1f;为了消除人际随机差异&#xff0c;提取恒定参数&#xff0c;在语际变异中找到共性。 引言 声调的主要载体就是基频。但是对声调的感知会因人而异&#xff0c;例如某个听感上的高升调&#xff0c;不同的调查人员可能会分别描写成 […

Nginx的负载均衡

Nginx不仅可以作为一个web服务器或反向代理服务器&#xff0c;还可以按照权重、轮询、ip_hash、URL_hash等多种方式实现对后端服务器的负载均衡。 负载均衡的概念&#xff1a; 负载均衡就是将负载分摊到多个操作单元上执行&#xff0c;从而提高服务的可用性和相应速度&#xf…

数据仓库、数据中台、数据湖都是什么?

相信很多人都在最近的招聘市场上看到过招聘要求里提到了数据仓库、数据中台&#xff0c;甚至还有数据湖&#xff0c;这些层出不穷的概念让人困扰。今天我就来跟大家讲一讲数据仓库、数据中台以及数据湖的概念及区别。 数据库 在了解数据仓库、数据中台以及数据湖之前&#xff…

JDBC

JDBC核心技术 讲师&#xff1a;宋红康 微博&#xff1a;尚硅谷-宋红康 第1章&#xff1a;JDBC概述 1.1 数据的持久化 持久化(persistence)&#xff1a;把数据保存到可掉电式存储设备中以供之后使用。大多数情况下&#xff0c;特别是企业级应用&#xff0c;数据持久化意味着将内…

【java web篇】Tomcat的基本使用

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

ceph介绍、原理、架构、算法...个人学习记录

前言 之前公司安排出差支援非结构化项目&#xff0c;采用springcloud(redismysql数据冷热处理)s3escephkafka还涉及一些区块链技术等等…&#xff0c;在与大佬的沟通交流下对ceph产生了兴趣&#xff0c;私下学习记录一下&#xff1b;后续工作之余会采用上面相关技术栈手动实现不…

Python模块化编程_Python编程之路

之前跟大家讲的是一些python的数据基础&#xff0c;从这篇文章开始&#xff0c;我们开始正式学习python的模块化编程 下面我们解释一下什么叫做模块 之前已经讲过怎么去定义一个方法&#xff0c;如果你是用python交互器(自带交互器&#xff0c;或者是ipython)来学习定义方法的…

4 通道 3.2GSPS(2 通道 6.4GSPS) 12 位 AD 采集子卡模块

FMC134 是一款 4 通道 3.2GSPS&#xff08;或者配置成 2 通道 6.4GSPS&#xff09; 采样率的 12 位 AD 采集 FMC子卡模块&#xff0c;该板卡为 FMC标准&#xff0c;符 合 VITA57.4 规范&#xff0c;可以作为一个理想的 IO 模块耦合至 FPGA 前端&#xff0c; 射频模拟信号数字化…

c语言经典例题-循环结构程序设计

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 求各位数字之积&#xff1a; 本关任务&#xff1a;计算正整数num的各位上的数字之积。 例如&#xff1a; 输入&am…

Elasticsearch:构建自动补全功能 - Autocomplete

什么是自动补全&#xff08;autocomplete&#xff09;功能呢&#xff1f;我们举一个很常见的例子。 每当你去谷歌并开始打字时&#xff0c;就会出现一个下拉列表&#xff0c;其中列出了建议。 这些建议与查询相关并帮助用户完成查询。 Autocomplete 正如维基百科所说的&#xf…

vulnhub raven2复现

1.扫描全网段&#xff0c;找出了存活主机ip为192.168.85.144 nmap 192.168.85.0/24 2.nmap扫描端口 nmap -p1-65535 192.168.85.144 3.访问此网站&#xff0c;没找到什么地方可以利用漏洞 &#xff0c;查看中间件为wordpress 4.使用dirb对该网站进行目录扫描 dirb http://1…

刷题笔记3 | 203. 移除链表元素、707设计链表,206.反转链表

目录 203. 移除链表元素 707、设计链表 206.反转链表 203. 移除链表元素 题意&#xff1a;删除链表中等于给定值 val 的所有节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 示例 2&#xff1a; 输入&#xff1a;h…

18跨越语言:不同语言间进行RPC通信

在最开始介绍gRPC时我们讲到,gRPC具有灵活的兼容性,可以支持很多种编程语言,下面我们就使用在后端领域最常用的两种编程语言Go和Java,来体验一下gRPC在不同语言的项目间是如何进行通信的。 逻辑架构 由上图我们可以看出,Go语言设计gRPC的服务端,Java语言设计gRPC的客户端…

欢迎来到 BharatBox,这是一个以来自印度的知名艺术家和品牌为特色的文化元宇宙中心

通过 Brinc 的客户 Heftyverse 娱乐公司&#xff0c;将印度艺术家、电影制片厂、体育品牌和音乐公司聚集在这个全新虚拟中心。 The Sandbox 与 Brinc 的联营公司推出 BharatBox&#xff0c;这是一个全新的文化中心&#xff0c;由来自印度的娱乐、艺术和体育范畴的主要合作伙伴组…

吴恩达监督机器学习:回归和分类(一)

文章目录机器学习简介机器学习是什么quiz监督学习回归问题分类问题quiz无监督学习聚类问题quiz练习测试&#xff1a;监督学习与无监督学习线性回归线性回归模型第一部分基本术语线性回归模型第二部分quiz选学实验&#xff1a;线性回归模型代价函数公式quiz代价函数的直观理解qu…

SpringBoot+Seata在多数据源和feign中的简单使用

SpringBootSeata简单使用 目录seata执行过程安装seata下载seata使用自定义配置文件,NACOS为注册中心结合springboot实现AT模式1.多数据源引入依赖bootstrap.yml配置在使用的方法上用GlobalTransactional注解调用接口正常时调用接口报错时回滚2.配合feignseata优缺点seata执行过…

「并发编程实战」接口幂等性设计的最佳实现(8种实现方案)

「并发编程实战」接口幂等性设计的最佳实现&#xff08;8种实现方案&#xff09; 文章参考&#xff1a; 实战&#xff01;聊聊幂等设计 基于幂等表思想的幂等实践 追忆四年前&#xff1a;一段关于我被外企CTO用登录注册吊打的不堪往事 弹力设计篇之“幂等性设计” 一、什么是幂…

【Spark分布式内存计算框架——Structured Streaming】2. Structured Streaming 核心设计与编程模型

核心设计 2016年&#xff0c;Spark在2.0版本中推出了结构化流处理的模块Structured Streaming&#xff0c;核心设计如下&#xff1a; 第一点&#xff1a;Input and Output&#xff08;输入和输出&#xff09; Structured Streaming 内置了很多 connector 来保证 input 数据源…

永春堂1300系统开发|解析永春堂1300模式商城的五大奖项

电商平台竞争越来越激烈&#xff0c;各种营销方式也是层出不穷&#xff0c;其中永春堂1300营销模式&#xff0c;以其无泡沫和自驱动性强等特点风靡一时。在这套模式中&#xff0c;虽然单型价格差异较大&#xff0c;但各种奖励的设计&#xff0c;巧妙的兼顾了平台和所有会员的利…