线程池的简单介绍以及实现一个线程池
创始人
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);}});}}
}

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...