利用线程池来创建和管理线程

SAP S/4HANA 可扩展性 – 面向初学者的简化指南 可扩展性(Extensibility)是 SAP ECC 和 SAP S/4HANA 的一项关键功能。它使客户能够通过定制其业务流程来创造竞争优势,并使合作伙伴能够通过量身定制的解决方案来丰富核心 ECC 或 S/4HANA。在过去的几十年中,SAP 的 on-premise 版本客户和合作伙伴主要使用经典的 ABAP 扩展性来扩展他们的 ERP 解决方案。经典扩展性允许 ABAP 开发人员使用甚至修改所有 SAP 对象。尽管经典扩展性非常强大和灵活,但在当今的云世界中,它已不再是一个好的选择。 阅读详情

        传统的创建线程的方式有两种:继承Thread类和实现Runnable接口,Java SE5的java.util.concurrent包中放入执行器(Executor)将为你管理Thread对象,先来回顾以传统方法创建线程的方式:

public class CreateThreadByImplRunnable implements Runnable{
	protected int countDown = 10;
	private static int taskCount = 0;
	private int id = taskCount++;
	
	public CreateThreadByImplRunnable(int countDown){
		this.countDown = countDown;
	}
	
	public String statues(){
		return "#" + id + "(" + 
				(countDown > 0 ? (countDown + "),"): "Liftoff!)");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(countDown-- > 0){
			System.out.print(statues());
			Thread.yield();   //告知线程调度器此时是切换到其他线程的最佳时机
		}
		System.out.println();
	}
	
	public static void main(String[] args) throws InterruptedException {
		Thread thread = new Thread(new CreateThreadByImplRunnable(10));
		System.out.println("单个任务:");
		thread.start();
		/**重复调用start方法运行时报错*/
		//thread.start();
		thread.join();
		System.out.println();
		System.out.println("多个任务:");
		for(int i = 0;i < 10;i++){
			new Thread(new CreateThreadByImplRunnable(10)).start();
		}
	}
}

将上述代码改成以线程池创建线程(利用CachedThreadPool类)

public class CreateThreadByExecutor {
	
	//用CachedThreadPool来执行任务,CachedThreadPool会为每个任务创建一个线程
	@Test
	public void test1(){
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i = 0;i < 100;i++){
			exec.execute(new CreateThreadByImplRunnable(10)); //从结果来看,与自己手动创建线程没什么区别
		}
		exec.shutdown(); 
	}
}

值得注意的是shutdown方法,该方法可以防止新任务被提交给这个Executor,下面介绍一下newCachedThreadPool方法:

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

该方法是Executors类的静态方法,返回一个Executor,类似于工厂模式,再来看下ThreadPoolExecutor类:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

5个参数,意义分别如下:

corePoolSize为0,maximumPoolSize为Integer.MAX_VALUE,意味着线程数量可以为任意整数

keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;

采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,没什么实际作用

那么使用CachedThreadPool有什么好处呢?最明显的是可以复用线程,传统分方式每一个任务都会创建一个线程,而使用CachedThreadPool首先会检查线程池里有没有空闲线程,如果有直接拿来用,没有的话再创建。

除了CachedThreadPool类以外,concurrent还提供了另外3种线程池FixedThreadPool、SingleThreadExecutor、ScheduiedThreadPool,分别作介绍

(1)FixedThreadPool

    使用有线的线程集来执行任务:

public class FIxedThreadPoolTest {
	public static void main(String[] args) {
		Executor exec = Executors.newFixedThreadPool(5);
		for(int i = 0;i < 10;i++){
			exec.execute(new RunClass());
		}
	}
	
	public static class RunClass implements Runnable{
		private static int count = 0;
		protected int threadNo = ++count;

		@Override
		public void run() {
			// TODO Auto-generated method stub
			System.out.println("Thread"	+ threadNo);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
}

输出结果(不固定):

Thread4
Thread5
Thread1
Thread2
Thread3
Thread6
Thread7
Thread10
Thread9
Thread8

在上述代码中,创建FixedThreadPool时我给它大小设定为5,然后让它去执行10个任务,为了体现FixedThreadPool与CachedThreadPool的不同之处让每个任务至少持续1秒,这样做有什么效果呢?从结果输出来看有两个效果:

1、结果看起来无序,实际前5个任务必然比后5个任务先执行

2、后5个任务大约等待1秒后才开始执行

其实这个不难理解,ThreadPool里维护着一个workQueue,当ThreadPool里的处于Running状态的线程数饱和时,新的任务就会放到WorkQueue里,WorkQueue是用LinkedBlockingQueue实现,关于LinkedBlockingQueue,它最大的特点就是阻塞,这里不做深究

(2)SingleThreadExecutor

    SingleThreadExecutor就像是数量为1的FixedThreadPool。如果向SingleThreadExecutor提交多个任务它会按照提交顺序      一个一个执行

(3)ScheduledThreadPool

    主要适用那些需要定时或周期性执行的任务,示例代码如下:

public class ScheduledThreadPoolTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ScheduledExecutorService secs = Executors.newScheduledThreadPool(5);
		secs.schedule(new RunTask(), 3, TimeUnit.SECONDS);    //延迟3秒执行
		secs.scheduleAtFixedRate(new RunTask(), 1, 3, TimeUnit.SECONDS);  //1秒后每3秒执行一次
	}
	
	public static class RunTask implements Runnable{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			System.out.println("ScheduledThreadPool Test");
		}
		
	}
}

总结:

    为了更好的维护线程的使用及提高性能,Java SE5推出了线程池的概念,提供4种线程池的实现方式,分别为:CachedThreadPool、FixedThreadPool、SingleThreadExecutor以及ScheduledThreadExecutor,在日常开发中应当根据业务场景合理使用线程池技术,本人并不反对滥用线程池技术,对个人学习来说,滥用好过不用,但是一定要在前期的滥用中吸取经验,最后方能精用

【Simulink教程案例9】基于simulink的BPSK,QPSK调制解调通信系统建模与仿真——使用simulink自带模块设计 BPSK (Binary Phase Shift Keying)-------二进制相移键控。是把模拟信号转换成数据值的转换方式之一,利用偏离相位的复数波浪组合来表现信息键控移相方式。BPSK使用了基准的正弦波和相位反转的波浪,使一方为0,另一方为1,从而可以同时传送接受2值(1比特)的信息。BPSK的映射关系如下所示:BPSK调制过程将输入的1010二进制数据中的0都转化为-1,使得非极性码变为极性码。 阅读详情

相关推荐

单细胞marker基因表达密度图-(还有一个包装函数)

我们借助Nebulosa,将上面的过程包装为一个函数,还是那句话,受累麻烦的事我们来解决,您轻松即可,先看看函数参数:需要注意的是,如果你只想框选某一类celltype,理想模式是这群celltype是单独聚类的,没有散落在其他类群,否则将会全部框选,效果不好,建议使用AI/PS添加。需要注意,这里我算是投机取巧了,用了一个和这个作图毫无关系的包ggnetwork,主要的目的是用他的theme_blank()主题,一次性将所有清空,当然也可以自己慢慢写,不过有现成的,为啥不用呢?这质感不就上去了嘛。

qq_42090739的博客 1372

Java线程死亡的几种情况

Java线程会议如下三种方式结束,结束后就处于死亡状态 1、run()或者call()方法执行完成,线程正常结束; 2、线程抛出一个未捕获的Exception或Error; 3、直接调用该线程的stop()方法来结束该线程; 注意:当主线程结束时,其他线程不受任何影响,并不会随之结束。一旦子线程启动起来后,它就拥有和主线程相同的地位,不会受到主线程结束的影响。 为了测试某个线程是否已经死亡...

蚂蚁学Python 2711

告别复杂配置!用GuidosToolbox 3.0做MSPA景观格局分析,从安装到出图全记录

本文详细介绍了如何使用GuidosToolbox 3.0进行MSPA景观格局分析,从安装配置到出图全流程。涵盖环境准备、数据预处理、参数设置、结果解读及可视化技巧,帮助用户快速掌握这一生态安全评估工具。特别针对安装教程中的常见问题提供解决方案,提升分析效率。

weixin_29248313的博客 490

线程池创建和简单使用

线程池的定义和简单使用

小小葩的博客 822

网络攻防技术——MD5碰撞试验

一、题目 本次实验主要是加深大家对MD5碰撞及其原理的理解,使用SEED实验环境中的工具及编程语言,完成以下任务: a)使用md5collgen生成两个MD5值相同的文件,并利用bless十六进制编辑器查看输出的两个文件,描述你观察到的情况; b)参考Lab3_task2.c的代码,生成两个MD5值相同但输出不同的两个可执行文件。 c)参考Lab3_task3.c的代码,生成两个MD5值相同但代码行为不相同的可执行文件。 d)回答问题:通过上面的实验,请解释为什么可以做到不同行为的两个可执行文件具有相同的M

学习记录 3622

Unity采样器过多导致URP默认的Lit.Shader报错(shader error in ‘universal render pipeline/lit’: maximum ps_4_0 samp)

Shader中多个Sample Texture2D,Sample Texture3D或者类似节点的使用,该类节点都需要一个采样器,如果Shader使用超过了16个纹理采样器,如多个Base Color,Normal Map等,就容易超出。是因为每种Shader Model和GPU都有一个对纹理采样器数量的限制,是因为每个采样器都需要在显卡占用一个独立的寄存器,而寄存器的数量是有限的,当超过限制,显卡无法分配更多的寄存器给新的采样器,因此会导致编译错误。2.什么原因导致纹理采样器超出16个?

qq_41884036的博客 4235

线程的创建方式与线程池的使用

前面几天忙着写论文好久没更新文章了,不能这么懈怠,还是得随时进行学习的反馈。虽然前面的坑还没填完,但我现在又准备开新坑了o( ̄︶ ̄)o。目前计划开个新专栏专门整理一下java.util.concurrent,Java并发包,也当做是复习,这一篇呢就是这个新系列的第一篇文章,话不多说,直接开冲!首先,如果我们直接使用JDK封装好的构造函数自动创建线程会发生什么,答案是可能由于使用无界工作队列导致任务堆积或者直接创建新的线程转发任务导致过多线程资源,发生内存溢出的问题。如果自定义合适的线程池呢?

weixin_44153131的博客 818

0032期基于深度学习的大米识别-含数据集

083基于深度学习的手势识别小程序版本_含10多种模型包括alexnet、DenseNet、DLA、GoogleNet、Mobilenet、ResNet、ResNeXt、ShuffleNet、VGG、EfficientNet和Swin transformer等10多种模型。117nlp自然语言处理-文本情感分类-joy-sadness-anger-fear-love-surprise。运行02深度学习模型训练.py就会将txt文本中记录的训练集和验证集进行读取训练,训练好后会保存模型在本地。

grehtsfrs的博客 1508

java多线程创建runnable_Java线程池和runnables创建runnables

有很多方法可以做你想要的 . 您需要小心,不要最终创建太多线程 .以下是一个示例,您可以使用ExecutorCompletionService提高效率,也可以使用Runnable .import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent.Callable...

weixin_40003780的博客 232

Debian Buster 软件源失效问题

摘要:基于Debian Buster的ARM64设备因系统版本结束支持(EOL)导致apt update报错404。解决方案包括:1)改用Debian官方存档源(需禁用安全检查);2)升级至受支持的Debian 11/12版本(推荐);3)临时使用第三方镜像源(不推荐)。操作步骤涉及修改sources.list、处理NTP同步问题及清理残留配置。建议优先采用版本升级方案以获得持续安全更新,避免使用过时系统带来的安全隐患。文中提供了完整命令示例和操作记录供参考。

yy_xzz的博客 2179

Flink 运维监控与指标采集实战(Prometheus + Grafana 全流程)

Flink运维监控在实时计算场景中至关重要,因为Flink作业需要7×24小时稳定运行,对性能、资源、故障感知和状态变化的实时监控是保障系统稳定的关键。Flink自带的Metrics系统提供了基本的监控能力,但为了更全面的监控,Prometheus+Grafana成为最主流的解决方案。通过配置PrometheusReporter和Grafana仪表盘,可以实现对Flink作业的全面监控,包括CPU、内存、吞吐量、Checkpoint状态、KafkaSink性能等关键指标。此外,自定义指标采集和报警机制的配置

晴天彩虹雨的博客 1368

Java常见的线程池的创建及使用

本文主要介绍了线程池常见的创建方式、7个参数、线程池的拒绝策略以及自定义实现拒绝策略

zly03的博客 323

块存储:AIO的直接写流程注释

提交io流程中aio_write之前函数的注释,可参考“块存储:AIO的直接读流程注释”。

yiyeguzhou100的专栏 1335

线程池的设计理念是通过合理管理线程资源来优化性能和资源利用率,而不是一味地创建线程。线程池优先将任务放入队列而不是直接创建新线程,主要是基于以下几个原因:

通过先将任务放入队列,线程池可以根据任务的实际负载动态调整线程数量。如果线程池一开始就创建最大数量的线程,可能会导致系统资源被过度占用,影响其他任务的运行。通过先将任务放入队列,线程池可以逐步扩展线程数量,避免资源的浪费。过多的线程会导致频繁的上下文切换(context switching)和资源竞争(如锁竞争),从而降低系统的整体性能。线程的创建和销毁是相对昂贵的操作,尤其是在频繁创建和销毁线程的情况下,会显著增加系统的开销。线程池通过复用已有的线程来处理任务,可以避免频繁创建和销毁线程带来的性能损耗。

靡不有初,鲜克有终 346

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

线程池创建,执行流程

​ 相对前几个来说,该方法创建的线程池是较为特殊的一个线程池,该线程池的核心线程数为0,最大线程数为 Integer.MAX_VALUE=2147483647。这个线程池没有 核心线程数,并且该任务队列也不会存储任务队列,会直接判断线程数是否超过最大线程数,去创建新的该线程。通过线程池,可以不用去频繁的开启和关闭线程。当有一个线程要开启时,通过线程池中的线程开启。这个线程运行完毕时,将线程归还给线程池,用于后来的线程使用。​ 我们可以看到,通过一个int类型的参数,设置了核心线程数和最大线程数。

cfz1095858425的博客 2157

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

java线程池案例

简介 线程Thread是一个重量级资源,线程的创建、启动以及销毁都是比较耗费系统资源的,同时受限于系统资源的限制,线程的数量与系统性能是一种抛物线的关系,因此对线程的管理,是一种非常好的程序设计习惯,自JDK1.5起,utils包提供了ExecutorService[ɪɡˈzɛkjətɚ]线程池的实现。通俗的将:为了避免重复的创建线程,线程池的出现可以让线程进行复用。当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用。 一个线程池包括以下四个基

人生就像一场戏 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

线程池实现与讲解

希望打开这篇对你有所帮助。

看,未来的博客 8867

Qt中的线程池

线程池是多线程编程中常用的一种技术,可以帮助管理系统中的线程资源、提高程序的性能、帮助控制并发度、简化多线程编程、提高程序的稳定性。所以,线程池在Qt开发中具有重要的作用,在需要进行多线程编程的场景下,使用线程池是一个常见且有效的选择。

smallerxuan的博客 3477

c++实现线程池

线程池:简单地说,线程池 就是预先创建好一批线程,方便、快速地处理收到的业务。比起传统的到来一个任务,即 时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高。 在linux中,使用的是posix线程库,首先介绍几个常用的函数: 1 线程的创建和取消函数 pth

chenjianliangdehao的专栏 1万+

JUC 线程池

日志反应的比较清楚,我们的线程池只有2个线程,线程2 执行了两个提交的任务,f1 的结果为任务返回的结果,f2 的结果为我们提交任务是传的结果,f3 不返回结果(因为 Runnable 接口的 run 方法返回值为 void)这里的线程名称格式为:pool-[虚拟机中线程池编号]-thread-[线程编号],如 pool-1-thread-1,在实际使用时我们最好自定义线程名称,以提高日志的可读性,避免日后排查日志无法第一时间确定执行的线程。如果没有则继续等待,直到有空闲线程执行。

这个需求,做不了 1250

C++线程池管理

管理C++线程池涉及创建、调度和终止线程的机制,以有效地处理并发任务。以下是一个基本的线程池管理示例,包括线程池的创建、任务分配和线程池的销毁。

程序猿老樊的博客 931

Python中多线程和线程池的使用方法

上述代码中,我们定义了一个process函数,它接受一个列表作为参数,对列表中的每个元素进行运算,并将结果保存到另一个列表中。在上面的代码中,我们首先定义了一个GetHtmlThread类,继承自threading.Thread类,然后在类的构造函数中传入需要爬取的URL。在主程序中,我们创建了5个线程,每个线程都执行task函数,并传入不同的参数。但是,这种单线程爬取的方式效率较低,因为在获取HTML代码的时候需要等待响应,而在等待响应的过程中CPU会空闲,无法充分利用计算机的性能。

weixin_47831992的博客 4817

线程池详解

本文介绍线程池的思想以及线程池的执行流程。

DC1020的博客 1072

使用线程池创建多线程

新增方式二:使用线程池 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用。类似于生活中的公交交通工具。 好处: 提高响应速度(减少了创建新线程的时间) 降低资源消耗(重复利用线程池中线程,不需要每次都创建) 便于线程管理 corePoolSize:核心池的大小 maximumPoolSize:最大线程数 keepaliveTime:线程没有任务时最

来杯奶茶 1447

Java线程池

线程池

Java领域 1万+

java线程池杂谈(线程池创建和运行)

继之前写过阿里编码规约对线程池的创建,关于线程池还想再写写自己的理解。1、为啥要有线程池2、线程池怎么创建3、线程池是怎么运行的4、Executors创建线程的弊端下面来一一说一下自己的理解(有说的不对的还请同学不吝赐教)

高山仰止,景行行止 1789
下一篇: java I/O之File类:遍历目录树
coder_no
博客等级 码龄9年 1粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值