当前位置: 首页 > article >正文

线程池(重要)

标准库中的线程池

使⽤ Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.
返回值类型为 ExecutorService
通过 ExecutorService.submit 可以注册⼀个任务到线程池中
ExecutorService pool = Executors.newFixedThreadPool( 10 );
pool.submit( new Runnable () {
@Override
public void run () {
System.out.println( "hello" );
}
});

Executors 创建线程池的⼏种⽅式

newFixedThreadPool: 创建固定线程数的线程池
newCachedThreadPool: 创建线程数⽬动态增⻓的线程池.
newSingleThreadExecutor: 创建只包含单个线程的线程池.
newScheduledThreadPool: 设定 延迟时间后执⾏命令,或者定期执⾏命令. 是进阶版的 Timer.
Executors 本质上是 ThreadPoolExecutor 类的封装
面试问题

ThreadPoolExecutor 提供了更多的可选参数, 可以进⼀步细化线程池⾏为的设定.

corePoolSize: 正式员⼯的数量. (正式员⼯, ⼀旦录⽤, 永不辞退)
maximumPoolSize: 正式员⼯ + 临时⼯的数⽬. (临时⼯: ⼀段时间不⼲活, 就被辞退).
keepAliveTime: 临时⼯允许的空闲时间.
unit: keepaliveTime 的时间单位, 是秒, 分钟, 还是其他值.
workQueue: 传递任务的阻塞队列
(重要 )threadFactory: 创建线程的⼯⼚, 参与具体的创建线程⼯作. 通过不同线程⼯⼚创建出的线程相当于
对⼀些属性进⾏了不同的初始化设置.
1.RejectedExecutionHandler: 拒绝策略, 如果任务量超出公司的负荷了接下来怎么处理.
2.AbortPolicy(): 超过负荷, 直接抛出异常.
3.CallerRunsPolicy(): 调⽤者负责处理多出来的任务.
4.DiscardOldestPolicy(): 丢弃队列中最⽼的任务.
5.DiscardPolicy(): 丢弃新来的任务.

实现线程池

核⼼操作为 submit, 将任务加⼊线程池中
使⽤ Worker 类描述⼀个⼯作线程. 使⽤ Runnable 描述⼀个任务.
使⽤⼀个 BlockingQueue 组织所有的任务
每个 worker 线程要做的事情: 不停的从 BlockingQueue 中取任务并执⾏.
指定⼀下线程池中的最⼤线程数 maxWorkerCount; 当当前线程数超过这个最⼤值时, 就不再新增
线程
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class MyThreadpool{
    private BlockingQueue<Runnable> queue=null;/使⽤⼀个 BlockingQueue 组织所有的任务

   //// 创建了⼀个固定数量的线程池
    public MyThreadpool(int n){

//ArrayBlockingQueue为任务队列,容量为1000
        queue=new ArrayBlockingQueue<>(1000);
        while(n>0){
            Thread t=new Thread(()->{
                while (true){
                    try {
                        Runnable arr=queue.take();//使⽤ Runnable 描述⼀个任务. 
                        arr.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            t.start();
            n--;
        }
    }
                      //使⽤ Runnable 描述⼀个任务.
    public void submit(Runnable stak) throws InterruptedException {/核⼼操作为 submit, 将任务加⼊线程池中
        queue.put(stak);
    }
}
//线程池
public class work2 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadpool per=new MyThreadpool(10);
        int i=0;
        for( i=0;i<100;i++){
            int id=i;
            per.submit(()->{
                System.out.println(Thread.currentThread().getName()+" id "+id);
            });
        }
    }
}

 对⽐线程和进程

 线程的优点

1. 创建⼀个新线程的代价要⽐创建⼀个新进程⼩得多
2. 与进程之间的切换相⽐,线程之间的切换需要操作系统做的⼯作要少很多
3. 线程占⽤的资源要⽐进程少很多
4. 能充分利⽤多处理器的可并⾏数量
5. 在等待慢速I/O操作结束的同时,程序可执⾏其他的计算任务
6. 计算密集型应⽤,为了能在多处理器系统上运⾏,将计算分解到多个线程中实现
7. I/O密集型应⽤,为了提⾼性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

进程与线程的区别

1. 进程是系统进⾏资源分配和调度的⼀个独⽴单位,线程是程序执⾏的最⼩单位。
2. 进程有⾃⼰的内存地址空间,线程只独享指令流执⾏的必要资源,如寄存器和栈。
3. 由于同⼀进程的各线程间共享内存和⽂件资源,可以不通过内核进⾏直接通信。
4. 线程的创建、切换及终⽌效率更⾼。

http://www.kler.cn/news/368343.html

相关文章:

  • 大厂面经:京东嵌入式面试题及参考答案
  • Linux基础知识作业
  • Qt中使用线程之QThread
  • Python -- 网络爬虫
  • 飞书文档解除复制限制
  • 无需依赖闭源模型!司南CompassJudger为AI评测带来新选择
  • 位运算算法及习题 ,丢弃的数字 , 两整数之和 ,只出现一次的数字II
  • Java 线程池:深入理解与高效应用
  • C语言 | Leetcode C语言题解之第515题在每个树行中找最大值
  • 《Knowledge Graph Enhanced Multimodal Transformer for Image-Text Retrieval》中文校对版
  • NtripShare Cloud平台之CORS服务之基准站RTCM坐标编辑
  • Apache paino DML操作实战
  • Python数据分析——Numpy
  • Git快速上手
  • Java实现 itext PDF文件打印水印(文字和图片水印)
  • Vue前端开发:双向数据绑定之v-model与修饰符
  • 基于STM32的水产品运输监测系统设计与实现
  • 湖南(满意度调查)源点咨询 市场调研中定量调研方式的运用技巧
  • 使用ceph-csi把ceph-fs做为k8s的storageclass使用
  • 基于vite和vue3、 eslint、prettier、stylelint、husky规范
  • Python实现贝叶斯优化器(Bayes_opt)优化简单循环神经网络分类模型(SimpleRNN分类算法)项目实战
  • count(1)、count(*)、count(主键)、count(字段)区别
  • openlayers 封装加载本地geojson数据 - vue3
  • git stash和git stash pop
  • Linux之nginx离线安装
  • 图文详解ChatGPT-o1完成论文写作的全流程