`
y806839048
  • 浏览: 1083184 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

深入理解线程和线程池

阅读更多

关于线程和线程池的学习,我们可以从以下几个方面入手:

 

第一,什么是线程,线程和进程的区别是什么

 

第二,线程中的基本概念,线程的生命周期

 

第三,单线程和多线程

 

第四,线程池的原理解析

 

第五,常见的几种线程池的特点以及各自的应用场景

 

 线程池是建立好了线程,外部不需要建立线程,有任务直接放入现有空闲线程

类似长链接,连接不释放,有通讯直接用建立好的连接管道

dubbo   tcp长链接---适用于高并发小数据    序列化方式是Hessian+nio

    tcp短链接---适用于大数据,并发低    

 springcloud   http报文长,占带宽  传输的大小和序列化方式都效率低于rpt  ---导致大量并发性能差

 

一、

 

线程,程序执行流的最小执行单位,是行程中的实际运作单位,经常容易和进程这个概念混淆。那么,线程和进程究竟有什么区别呢?首先,进程是一个动态的过程,是一个活动的实体。简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者。可以说,进程中包含了多个可以同时运行的线程。

 

 

 

二、

 

线程的生命周期,线程的生命周期可以利用以下的图解来更好的理解:

 

 

第一步,是用new Thread()的方法新建一个线程,在线程创建完成之后,线程就进入了就绪(Runnable)状态,此时创建出来的线程进入抢占CPU资源的状态,当线程抢到了CPU的执行权之后,线程就进入了运行状态(Running),当该线程的任务执行完成之后或者是非常态的调用的stop()方法之后,线程就进入了死亡状态。而我们在图解中可以看出,线程还具有一个则色的过程,这是怎么回事呢?当面对以下几种情况的时候,容易造成线程阻塞,第一种,当线程主动调用了sleep()方法时,线程会进入则阻塞状态,除此之外,当线程中主动调用了阻塞时的IO方法时,这个方法有一个返回参数,当参数返回之前,线程也会进入阻塞状态,还有一种情况,当线程进入正在等待某个通知时,会进入阻塞状态。那么,为什么会有阻塞状态出现呢?我们都知道,CPU的资源是十分宝贵的,所以,当线程正在进行某种不确定时长的任务时,Java就会收回CPU的执行权,从而合理应用CPU的资源。我们根据图可以看出,线程在阻塞过程结束之后,会重新进入就绪状态,重新抢夺CPU资源。这时候,我们可能会产生一个疑问,如何跳出阻塞过程呢?又以上几种可能造成线程阻塞的情况来看,都是存在一个时间限制的,当sleep()方法的睡眠时长过去后,线程就自动跳出了阻塞状态,第二种则是在返回了一个参数之后,在获取到了等待的通知时,就自动跳出了线程的阻塞过程

 

三、

 

什么是单线程和多线程?

 

单线程,顾名思义即是只有一条线程在执行任务,这种情况在我们日常的工作学习中很少遇到,所以我们只是简单做一下了解

 

多线程,创建多条线程同时执行任务,这种方式在我们的日常生活中比较常见。但是,在多线程的使用过程中,还有许多需要我们了解的概念。比如,在理解上并行和并发的区别,以及在实际应用的过程中多线程的安全问题,对此,我们需要进行详细的了解。

 

并行和并发:在我们看来,都是可以同时执行多种任务,那么,到底他们二者有什么区别呢?

 

并发,从宏观方面来说,并发就是同时进行多种时间,实际上,这几种时间,并不是同时进行的,而是交替进行的,而由于CPU的运算速度非常的快,会造成我们的一种错觉,就是在同一时间内进行了多种事情

 

而并行,则是真正意义上的同时进行多种事情。这种只可以在多核CPU的基础下完成。

 

还有就是多线程的安全问题?为什么会造成多线程的安全问题呢?我们可以想象一下,如果多个线程同时执行一个任务,name意味着他们共享同一种资源,由于线程CPU的资源不一定可以被谁抢占到,这是,第一条线程先抢占到CPU资源,他刚刚进行了第一次操作,而此时第二条线程抢占到了CPU的资源,name,共享资源还来不及发生变化,就同时有两条数据使用了同一条资源,具体请参考多线程买票问题。这个问题我们应该如何解决那?

 

  有造成问题的原因我们可以看出,这个问题主要的矛盾在于,CPU的使用权抢占和资源的共享发生了冲突,解决时,我们只需要让一条线程战歌了CPU的资源时,阻止第二条线程同时抢占CPU的执行权,在代码中,我们只需要在方法中使用同步代码块即可。在这里,同步代码块不多进行赘述,可以自行了解。

 

四,线程池

 

又以上介绍我们可以看出,在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。

 

线程池:Java中开辟出了一种管理线程的概念,这个概念叫做线程池,从概念以及应用场景中,我们可以看出,线程池的好处,就是可以方便的管理线程,也可以减少内存的消耗。

 

那么,我们应该如何创建一个线程池那?Java中已经提供了创建线程池的一个类:Executor

 

而我们创建时,一般使用它的子类:ThreadPoolExecutor.

 

public ThreadPoolExecutor(int corePoolSize,  

                              int maximumPoolSize,  

                              long keepAliveTime,  

                              TimeUnit unit,  

                              BlockingQueue<Runnable> workQueue,  

                              ThreadFactory threadFactory,  

                              RejectedExecutionHandler handler)

这是其中最重要的一个构造方法,这个方法决定了创建出来的线程池的各种属性,下面依靠一张图来更好的理解线程池和这几个参数:(slector多路复用也是类似这种模型---nioEventLoop=selector+taskqueue

 

 

又图中,我们可以看出,线程池中的corePoolSize就是线程池中的核心线程数量,这几个核心线程,只是在没有用的时候,也不会被回收,maximumPoolSize就是线程池中可以容纳的最大线程的数量,而keepAliveTime,就是线程池中除了核心线程之外的其他的最长可以保留的时间,因为在线程池中,除了核心线程即使在无任务的情况下也不能被清除,其余的都是有存活时间的,意思就是非核心线程可以保留的最长的空闲时间,而util,就是计算这个时间的一个单位,workQueue,就是等待队列,任务可以储存在任务队列中等待被执行,执行的是FIFIO原则(先进先出)。threadFactory,就是创建线程的线程工厂,最后一个handler,是一种拒绝策略,我们可以在任务满了知乎,拒绝执行某些任务。

 

线程池的执行流程又是怎样的呢?

 

 

有图我们可以看出,任务进来时,首先执行判断,判断核心线程是否处于空闲状态,有空闲的就用来执行任务,如果不是,核心线程就先就执行任务,如果核心线程已满,则判断任务队列是否有地方存放该任务,若果有,就将任务保存在任务队列中,等待执行,如果满了,在判断最大可容纳的线程数,如果没有超出这个数量,就开创非核心线程执行任务,如果超出了,就调用handler实现拒绝策略。

 

handler的拒绝策略:

 

有四种:第一种AbortPolicy:不执行新任务,直接抛出异常,提示线程池已满

 

             第二种DisCardPolicy:不执行新任务,也不抛出异常

 

             第三种DisCardOldSetPolicy:将消息队列中的第一个任务替换为当前新进来的任务执行

 

             第四种CallerRunsPolicy:直接调用execute来执行当前任务

 

五,四种常见的线程池:

 

CachedThreadPool:可缓存的线程池,该线程池中没有核心线程,非核心线程的数量为Integer.max_value,就是无限大,当有需要时创建线程来执行任务,没有需要时回收线程,适用于耗时少,任务量大的情况。

 

SecudleThreadPool:周期性执行任务的线程池,按照某种特定的计划执行线程中的任务,有核心线程,但也有非核心线程,非核心线程的大小也为无限大。适用于执行周期性的任务。

 

SingleThreadPool:只有一条线程来执行任务,适用于有顺序的任务的应用场景。

 

FixedThreadPool:定长的线程池,有核心线程,核心线程的即为最大的线程数量,没有非核心线程

 

参考:https://blog.csdn.net/weixin_40271838/article/details/79998327 

 

分享到:
评论

相关推荐

    多线程与线程池技术详解(图书配套)

    本套视频为同名图书的配套视频,图书预计在2021.4上市

    深入理解Java线程池(PPT:原理+代码)

    通过剖析Java中线程池的原理,解读Java线程池源码,并给出线程池调用的示例,帮助理解线程池的基本原理。

    深入理解Java之线程池

     如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务结束了,这样频繁创建线程会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。  那么有没有一种办法使得线程可以复用,是执行完一个...

    《深入理解 Rust 并发编程》

    线程和线程池: Rust 中线程的创建、管理和同步,包括使用 std::thread 创建线程、线程间的通信以及线程池的构建和使用。特别强调了线程池的重要性,如 rayon 和 crossbeam 提供的线程池,它们能够提高资源利用率和...

    SpringBoot线程池详解含完整示例(值得珍藏)

    Spring Boot中内置了多种线程池,为应用程序提供快速响应和高吞吐量的运行环境。线程池在Spring Boot中起...深入理解Spring Boot中的线程池,并根据实际需求进行合理的配置和使用,是每个Spring Boot开发者的必备技能。

    深入理解高并发编程-Java线程池核心技术

    多线程可以理解为在同一个程序中能够同时运行多个不同的线程来执行不同的任务, 这些线程可以同时利用 CPU 的多个核心运行。多线程编程能够最大限度的利用 CPU 的资源。如果某一个线程的处理不需要占用 CPU 资源时...

    C# CLR原理与线程池详解

    深入理解CLR线程池等原理,是.net编程高手进阶必经之路。。。本教程可以帮助你来了解CLR中的一些令人激动的特性。理解这些特性将更好的帮助你来理解CLR。

    深入理解Java 线程池

    主要介绍了Java 线程池的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下

    JAVA高质量并发详解,多线程并发深入讲解

    本书全面解析了Java并发编程的核心概念、原理和实践,帮助读者深入理解多线程并发编程的精髓,提升编程能力和系统性能。 书中首先介绍了并发编程的基础知识,包括线程的基本概念、线程的生命周期、线程安全等问题。...

    Java Core Sprout:基础、并发、算法

    Java Core Sprout:一个萌芽阶段的Java核心知识库。 ...常用集合 数组列表/向量 链表 哈希映射 哈希集 ...深入理解线程通信 一个线程召集的诡异事件 线程池中你不可错过的一些细节 『ARM包入坑指北』之队列

    讲给女朋友听的java多线程(2万字深入理解多线程,有实例代码辅助理解)

    读完本文大概需要30分钟左右,本文有大量的实例代码和典型例题帮助大家理解java多线程。虽然多线程比较难以理解,仅靠一篇文章恐怕搞不定。但读完本文最起码能让你搞懂java多线程的70%以上,至于熟练运用,还是得...

    Java 多线程编程面试集锦20道问题解答Java多线程编程高难度面试题及解析

    在当今高并发的应用场景下,对多线程编程的理解和应用是评估面试者的重要指标。通过这些高难度问题,您将全面掌握Java多线程编程的核心概念、技术和最佳实践。 每个问题都包含了深入的答案解析,涵盖了多线程编程的...

    【2018最新最详细】并发多线程教程

    9.深入理解AbstractQueuedSynchronizer(AQS) 10.彻底理解ReentrantLock 11.深入理解读写锁ReentrantReadWriteLock 12.详解Condition的await和signal等待通知机制 13.LockSupport工具 14.并发容器之ConcurrentHashMap...

    java并发编程_线程池的使用方法(详解)

    下面小编就为大家带来一篇java并发编程_线程池的使用方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    【并发编程】深入理解JMM.pdf

    高级开发者:需要深入理解并发编程原理,解决复杂并发问题的资深开发者。 计算机科学学生:正在学习计算机科学,对并发和分布式系统感兴趣的学生。 系统架构师:负责设计和优化大型系统架构,需要了解并发编程以提高...

    14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf

    14、深入理解井发可见性、有序性、原子性与JMM内存模型 (1).pdf 15、CPU缓存架构详解&高性能内存队列Disruptor 实战 (1).pdf 16、常用并发设计模式精讲 (1).pdf designpattern.zip disruptor.zip forkjoin.zip jmm(1...

    C++11标准实现的线程池以及在此基础上实现的仿cron功能的定时器

    然后再针对定时任务的处理实际上也是在线程池中的一个工作线程中进行的处理。另外,需说明的是原始码的出处:https://github.com/Ahajha/CTPL,只是github上的必须满足c++20的标准才能编译通过,这儿为了平日工程的...

    java面试笔试资料包括JAVA基础核心知识点深度学习Spring面试题等资料合集.zip

    深入理解多线程实现的另一种方式Callable.docx 红黑树简介.docx 线程死锁及解决办法.docx 线程锁之重入锁.docx 线程间的通信.docx 虚拟机内存结构和垃圾回收docx.docx 锁分类的了解.docx 集合的扩容机制.png ...

    Java并发理论知识框架总结

    本知识框架是对《Java并发编程实战》一书的总结,主要围绕基本线程和线程池的使用、线程使用中出现的三大问题以及如何解决这些问题出发总结出了这个知识框架,通过该框架能更加深入的去理解Java并发理论知识。

    上海某大厂java面试真题与解析

    3、"深入理解线程池工作原理,掌握Executor框架下四种线程池的创建与应用,有效提升系统资源利用率。#Java线程池 #性能优化" 4、"线程状态流转图解析,从New到Runnable,再到Running,直至Blocked或Dead,全面解析...

Global site tag (gtag.js) - Google Analytics