线程池的简单介绍以及实现一个线程池
创始人
2024-05-14 09:31:14
0

文章目录

  • 1、线程池存在的意义
  • 2、什么是线程池?
  • 3、线程池的使用
    • 2、java标准库中的线程池
    • 3、认识一下不同的线程池:
    • 4、认识一下线程池里的参数:
  • 4、实现一个简单的线程池

1、线程池存在的意义

线程存在的意义:使用进程来实现并发编程,造成资源浪费等,因此引入了线程,使用线程来实现并发编程,线程也叫“轻量级进程”,因为 创建、销毁、调度线程比创建、销毁、调度进程更高效;
但是当我们需要频繁的创建、销毁线程时,就会发现开销还是挺大的,因此我们引入了线程池;

2、什么是线程池?

线程池:顾名思义就是“存放线程的池子”;

3、线程池的使用

事先把线程创建好,放到“池”中,后面需要使用的时候直接从“池”里获取即可;如果线程使用完毕,接着放回“池”里面;

注意:从“池”中取出,放入线程比创建销毁线程更高效;因为前者是用户代码实现的,后者是操作系统内核完成的;


什么是操作系统内核?
内核是操作系统的内部核心程序,它向外部提供了对计算机设备的核心管理调用。我们将操作系统的代码分成2部分。内核所在的地址空间称作内核空间。而在内核以外的统称为外部管理程序,它们大部分是对外围设备的管理和界面操作。外部管理程序与用户进程所占据的地址空间称为外部空间。通常,一个程序会跨越两个空间。当执行到内核空间的一段代码时,我们称程序处于内核态,而当程序执行到外部空间代码时,我们称程序处于用户态;
概念有点抽象。举个例子:

去面馆吃饭,你正在吃面的时候突然 想喝冰红茶了,你有两种选择,第一种:自己到冰箱里面拿冰红茶,也就是上面说的“用户态”;第二种:让老板给你拿一瓶冰红茶送到你这里来;也就是上面说的“内核态”

相比于内核态来说,用户态的程序执行行为是可控的,就拿上述的面条例子来说,自己直接跑到冰箱拿冰红茶,就一定可以很快喝到冰红茶,但是如果让老板呢冰红茶送过来,什么时候可以喝到冰红茶就是不可预知的了,因为老板可能正在忙其他事情,等他忙完了才可以去拿冰红茶。因此,当使用系统调用,执行内核代码的时候,无法确定内核都要做哪些工作,整体的行为是不可控的;


2、java标准库中的线程池

 public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(10);//构造了有10个线程的线程池for (int i = 0; i < 100; i++) {int n = i;//将100个任务放到池子里,由池子里的线程来分配任务pool.submit(new Runnable() {@Overridepublic void run() {System.out.print(n + " ");}});}}

注意:1、当前是往线程池里放了100个任务,这100个任务又是由10个线程来平均分配的(并非严格的平均分配,某一个线程多几个任务也是正常的);
2、我们会发现,main线程结束了,但是整个进程还是没结束,因为线程池里的线程都是前台线程,而前台线程会阻止进程结束
问题一:为什么要将i的值保存起来呢?
在这里插入图片描述
这里的i是main线程的局部变量(即i在主线程的栈上),但是随着主线程代码的结束,主线程的栈就销毁了,如果主线程销毁的时候当前任务的在线程池里还没排到,但是此时的i就已经销毁了,所以将i的值在当前run的栈上也拷贝了一份(即n)


3、认识一下不同的线程池:

在这里插入图片描述

4、认识一下线程池里的参数:

在这里插入图片描述


4、实现一个简单的线程池

class myThreadPool {private BlockingQueue queue = new LinkedBlockingQueue<>();public myThreadPool(int k) {//创建线程,执行任务for(int i = 0;i < k;i++){Thread thread = new Thread( () -> {while(true){try{Runnable runnable = queue.take();//将任务从队列里拿出runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();}}public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);//将任务放到队列里面}
}
public class Test7 {public static void main(String[] args) throws InterruptedException {myThreadPool mythreadpool = new myThreadPool(10);//构造有10个线程的线程池for (int i = 0; i < 100; i++) {int n = i;mythreadpool.submit(new Runnable() {   //创建任务@Overridepublic void run() {System.out.println(n);}});}}
}

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...