首页 > 其他分享 >多线程

多线程

时间:2022-08-20 19:45:48浏览次数:47  
标签:多线程 Thread 队列 排队 线程 提交 执行

使用场景

  • 异步化
  • 并发化
  • 削峰填谷

Thread

Thread t = new Thread(() -> sout("hello from :") + Thread.currentThread().getName());
t.start();
  • 不建议使用, 数量无法控制, 假如runnable逻辑很慢, 造成线程堆积, 内存很快填满, CPU时间片调度消耗大
  • 线程数量规定:
    • CPU密集型, CPU核数 + 1, 比如图片处理, 视频转码...
    • IO密集型, 可以多一些, 比如操作数据库, RPC...
    • 两者皆有, 二分法性能测试取最优

基于阻塞队列的Executor

关注runnable逻辑和管理线程壳的消耗

SingleThreadExecutor

  • 可执行线程数为1, 多个提交排队, 执行顺序等于提交顺序
  • 队列大小无上限, 可能排队过长OOM

FixedThreadPool

  • 可执行线程数为设定值, 多个提交排队, 执行顺序不保证等于提交顺序
  • 队列大小无上限, 可能排队过长OOM
  • 由于线程壳不会销毁, 初始化可执行数过大容易leak

CachedThreadPool

  • 线程壳定期清理, 不容易leak, 但也导致一段空闲后可用壳过少, 再面对突发洪峰创建壳消耗大
  • 队列大小无上限, 可能排队过长OOM
  • 执行顺序不保证等于提交顺序

ScheduledThreadPool

  • 定时, 延时提交
ScheduledExecutorService thread = Executors.newScheduledThreadPool(1);
// 包含子线程执行时间的执行, 以下实际周期为1.5s
thread.scheduldWithFixedDelay(() -> {
    sleep(500);
    sout("hello" + System.currentTimeMillis());}
    (起始延时)1, (定时周期)1, TimeUnit.SECONDS);

// 不包含子线程执行时间的执行, 以下实际周期为1s
thread.scheduldAtFixedRate(() -> {
    sleep(500);
    sout("hello" + System.currentTimeMillis());}
    (起始延时)1, (定时周期)1, TimeUnit.SECONDS);

ThreadPoolExecutor

  • 留存一定的预备线程壳, 定期清理也不会减少到此数目以下corePoolSize(参考值200)
  • 最大可执行线程数, 防止OOM maximumPoolSize(参考值400)
  • 创建线程壳工厂 threadFactory
    • 可以指定线程名
    • 可以设置setUncaughtExceptionHandler, 同一处理子线程的未处理异常, 比如记录到日志, 注意默认子线程异常不影响父线程, 不设置会导致捕获不到
  • 排队队列满了处理策略 rejectExecutionHandler
    • 默认Abort, 可以抛出InvocationException, 返回状态码429

Callable

  • 在线程池里submit Thread没有返回值
  • 提交Callable可以有返回值, 返回类型为Future<T>
  • Future类还用于响应式编程

基于Map-Reduce的forkjoin线程池

  • 为了减少管理线程壳的overhead, 可以将大量待处理线程切分为少量块, 然后用单线程分别处理每个块, overhead也能减少
  • 效果不会比基于阻塞队列的线程池好, 极端情况下切分到线程单元, 等价于一个很大的阻塞队列线程池

基于Map-Reduce的并发流

  • 相比forkjoin, 无需手写切分动作

  • 并且除了切分好块后创建的线程壳, 调用者(主线程壳)也会加入算力, 所以默认切分块数为CPU核数 - 1

  • 改变默认块数

    ForkJoinPool = pool = new ForkJoinPool(123);
    pool.submit(() -> list.parallelStream().forEach().get());
    

标签:多线程,Thread,队列,排队,线程,提交,执行
From: https://www.cnblogs.com/rellik96/p/16593057.html

相关文章

  • 多线程基础知识!!!
    目录1.线程创建的三种方式1.1、继承Thread类(重点)1.2、实现Runnable接口(重点,推荐)1.3、实现Callable接口(了解)2.线程的五大状态3.Lamda表达式4.线程初进阶5.线程同步5.1、了解......
  • 【Java进阶】五分钟快速掌握JVM优化概念、常用命令、工具、JUC、多线程、GC等知识
    〇、概述1、资料 2、内容概括 一、概念(一)JVM (二)JUC (三)GC二、命令(一)JVM优化命令 (二)JUC命令三、工具(一)jdk工具......
  • java实现多线程的四种方式
    实现多线程的三种方式:继承Thread类、实现Runnable接口、使用Callable和Future接口、使用线程池创建线程一、继承Thread类,重写run方法publicclassMyThreadextendsTh......
  • 多线程中的安全问题
    目录synchronizedsynchronized的同步代码块synchronized的非静态同步方法synchronized的静态同步方法多入口和多窗口卖票的不同情况Lock锁synchronizedsynchronized格式......
  • Java实现多线程的四种方式
    java中实现多线程主要有四种方式:继承Thread类一,继承Thread类,重写run方法publicclassThreadTest{//主线程publicstaticvoidmain(String[]args){......
  • 初识多线程
    初始多线程实现多线程的方法继承Thread类(重点)实现Runnavle接口(重点)实现Caliable接口(了解,以后可能会学习到!)多线程分两种进程和线程进程每一个程序都是静态的,当......
  • JAVA之线程及多线程实现
    java的线程是什么1线程是一个程序的一条执行路径。我们之前启动程序后。main方法其他是一条独立的执行路径。2JAVA的多线程JAVA的多线程是指从软硬件实现多条执行路......
  • [记]Rust在多线程里使用串口
    1.toml[dependencies]serial="0.4.0"encoding="0.2.33"--usestd::io::{Read,Write};usestd::sync::{Arc,Mutex};usestd::thread;usestd::time::Dura......
  • 记录QT QSqlDatabase SQLite 多线程使用时报错..
    首先QSqlDatabase同一个实例,不能多线程使用.如果多线程使用,需要给每个线程创建一个QSqlDatabase实例,一般是用Map维护各个线程实例链接,key是线程ID,value就是QSqlDa......
  • 多线程.线程同步
    同步方法:synchronized同步块:synchronized(Obj){}并发:多个线程操作同一个资源队列和锁每个对象都有一个锁,sleep不会释放锁由于同一进程的多个线程共享同一块存储空间......