找回密码
 会员注册
查看: 22|回复: 0

千万别从系统中创建线程,看看从线程池中调用的线程的效率(Java实践篇)

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-11 00:13:22 | 显示全部楼层 |阅读模式
本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念!!!在当今这个多核处理器成为标配的时代,如何高效地利用计算资源已成为软件开发中不可忽视的关键因素。随着应用程序变得越来越复杂,对并发处理的需求也日益增长。试想一下,在一个繁忙的服务器上,如果每一个新任务都创建一个新的线程来处理,那么系统将不堪重负——频繁的线程创建和销毁不仅消耗大量的时间和内存,还可能导致系统性能急剧下降。前言为了解决这一问题,并实现更高效的资源管理,线程池的概念应运而生。线程池是一种用于管理和复用一组预先创建好的线程的方法它通过预先创建一定数量的工作线程并将其置于池中等待分配任务,从而避免了频繁创建和销毁线程带来的开销。而在本篇文章中,小编将延续上篇我们对线程池的初识,以及线程池的参数理解在篇文章中来实际运用并实现我们线程池的学习。线程池的使用线程池的实现一.线程池的使用在我们Java的标准库中就封装了很多不同参数列表的线程池,所代表的功能和原理大体上是相似的,但实际的使用细节和适用场景还是不同的。而小编这次主要带着小伙伴们了解两种我们实际开发中比较常见的两种线程池创建的方法他们都属于Executors这个类下的静态方法第一种:newFixedThreadPool()方法下的可自定义核心线程个数的一类方法第二种:newCachedThreadPool()方法下根据需求自动创建一定数量的非核心方法的一类方法1.newFixedThreadPool().代码展示packageThreadDemo.ThreadPoolDemo;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.ForkJoinPool;publicclassExecutorTest{publicstaticvoidmain(String[]args)throwsInterruptedException{//利用这个方法造一个线程池ExecutorServiceexecutorService=Executors.newFixedThreadPool(4);//循环遍历来打印每一个线程for(inti=0;i{Threadt=Thread.currentThread();System.out.println("submit:"+t.getName()+"正在运行"+id);});}//等待Thread.sleep(1000);//结束创建的所有线程executorService.shutdown();System.out.println("程序结束!");}}123456789101112131415161718192021222324252627282930313233343536373839.实际运用分析在上面的代码中首先我们创建线程池,并指定核心线程的个数在for循环中调用submit来重写run方法充分利用创建的这几个线程来完成我们需要的工作最终shutdown()来终止所有线程的结束。鱼式疯言上面我们通过newFixedThreadPool()创建指定数目的线程池这样的场景特别适用于我们知道这个场景是最大限度,并能够充分利用我们的线程池中的线程资源。2.newCachedThreadPool().代码演示packageTestDemo6;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.ThreadPoolExecutor;publicclassTest1{publicstaticvoidmain(String[]args){ //创建线程池ExecutorServiceexecutorService1=Executors.newCachedThreadPool(); //通过循环的方式进行线程的使用for(inti=0;i{Threadt=Thread.currentThread();System.out.println("当前线程名为:"+t.getName()+"id为"+id);});}//结束所有线程executorService1.shutdown();}}123456789101112131415161718192021222324252627.运用分析在上面的代码中首先我们创建了线程池,这里不需要传递参数,线程池会根据需求动态的创建一定数量的线程来进行工作。循环使用线程池来,在submit()中重写run方法来执行任务。最终在调用shutdown来终止线程。鱼式疯言这个线程池中最大的线程个数为Integer的最大取值,也就是21亿。这么大的线程池是非常适合我们Java程序员对于服务器的开发会用到这个线程池。二.线程池的实现我们知道了如何使用,那么我们就要往更深的层次去理解,如何通过这些线程池的功能,实现一份我们自己的简单线程池呢???🤔🤔🤔答案是可以的。这里小编只演示线程池有参数的newFixedThreadPool()的方法实现哦小伙伴只需要掌握到这种程度就足够了哦💖💖💖💖1.线程池实现展示classMyPoolThread{//用一个阻塞队列来存储工作任务BlockingQueuequeue=newArrayBlockingQueue(1000);publicMyPoolThread(intnThreads){for(inti=0;i{//使用while的方式让n个线程都存在//并且进行抢占执行while(true){try{Runnablet=queue.take();t.run();}catch(InterruptedExceptione){thrownewRuntimeException(e);}}});//创建线程thread.start();}}publicvoidmySubmit(Runnablerunnable){//添加任务try{queue.put(runnable);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}publicstaticvoidmain(String[]args){MyPoolThreadt=newMyPoolThread(5);//重写任务t.mySubmit(()->{for(inti=0;i{Threadt1=Thread.currentThread();System.out.println("当前线程名为:"+t1.getName()+"id为"+id);});}});}}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758592.实现原理在上述的代码中首先,定义一个阻塞队列来管理我们不同的任务,因为这里虽然是创建不同的线程,但是这里还是以任务为基本单位去执行的。其次进行构造方法传参过程,也是创建线程的过程来,并把每个任务出队列进行运行,然后线程抢占执行。当用户调用submit()方法时,我们就可以把每个任务都加入到对应的阻塞队列中按照先进先出的特点依次执行。鱼式疯言**细节分析**:上述while的目的是保证刚创建的线程不会结束,依然可以抢占执行。如果不使用while就会出现以下情况classMyPoolThread{//用一个阻塞队列来存储工作任务BlockingQueuequeue=newArrayBlockingQueue(1000);publicMyPoolThread(intnThreads){for(inti=0;i{//使用while的方式让n个线程都存在//并且进行抢占执行//while(true){try{Runnablet=queue.take();t.run();}catch(InterruptedExceptione){thrownewRuntimeException(e);}//}});//创建线程thread.start();}}publicvoidmySubmit(Runnablerunnable){//添加任务try{queue.put(runnable);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}publicstaticvoidmain(String[]args){MyPoolThreadt=newMyPoolThread(5);//重写任务t.mySubmit(()->{for(inti=0;i{Threadt1=Thread.currentThread();System.out.println("当前线程名为:"+t1.getName()+"id为"+id);});}});}}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859总结在本篇文章中,我们一共实践了两个知识点线程池的使用:我们学习到了两种线程池的使用案例:newFixedThreadPool(线程个数),以及newCachedThreadPool(无参数)的两种方法的使用,小伙伴一定要多加练习来掌握哦❣️❣️❣️❣️2.线程池的实现:我们的核心通过阻塞队列的方式循环创建线程并运行runnable方法来实现我们newFixedThreadPool()来实现。如果觉得小编写的还不错的咱可支持三连下(定有回访哦),不妥当的咱请评论区指正希望我的文章能给各位宝子们带来哪怕一点点的收获就是小编创作的最大动力💖💖💖
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-28 23:32 , Processed in 0.896673 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表