线程 线程池

1、什么是线程,线程和进程的区别是什么

        程序执行流最小单位。一个请求到系统会启动一个线程。

        一个进程一般包含多个线程,线程是实际运行的任务执行者。

2、线程中的基本概念,线程的生命周期

线程 线程池

线程 线程池

        1、线程创建后 ——> 进入就绪状态(Runnable 可运行的)

         后面看图1、2

3、单线程和多线程

        单线程

        多线程:创建多条线程同时执行任务

        并行:同一时间执行多个任务,一定是同时

        并发:处理多任务的能力,不一定同时,多核可以同时

        多线程并发:多线程处理任务,并且有用到共享资源,就要考虑多线程并发问题。

4、怎么处理多线程并发问题

        

5、线程池的原理解析

线程 线程池

 

        1、最重要的类:

                Executor :线程池类,是接口

                ThreadPoolExecutor : 线程池接口(Executor )的子类

        ThreadPoolExecutor 最重要的构造函数:

public ThreadPoolExecutor(
      int corePoolSize, //核心线程数,不会被回收的线程数
      int maximumPoolSize, //最大线程数
      long keepAliveTime, // 除了核心线程外其他线程空闲最长保留时间
      TimeUnit unit, // 计算keepAliveTime 时间的单位
      BlockingQueue<Runnable> workQueue, // 任务等待队列,FIFIO原则(先进先出)
      ThreadFactory threadFactory, // 线程工厂
      RejectedExecutionHandler handler // 拒绝策略,任务满的时候拒绝某些任务
)

        2、ThreadPoolExecutor  的使用

        使用:https://www.cnblogs.com/dafanjoy/p/9729358.html

        3、其他实现类:

        他们的实现都是调用 ThreadPoolExecutor  实现

        newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
        newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
        newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
        newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
        具体使用:Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor - 星辰之力 - 博客园

        

        4、为什么要用线程池、什么时候用线程池?

                每个请求都会对应一个线程,线程的创建、销毁对系统资源的开销比较大。JVM 中如果创建过多的线程,容易造成系统资源紧张或者系统崩溃。

                在线程生命周期过程中,创建线程、切换线程状态、终结线程,都要进行CPU调度。这些操作都需要耗费CPU资源

为什么要用线程池? - 小星星☆★ - 博客园

6、线程池处理流程

线程 线程池

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

7、有效使用线程池使用准则

        只要您遵循几条简单的准则,线程池可以成为构建服务器应用程序的极其有效的方法:

        (1)不要对那些同步等待其它任务结果的任务排队。这可能会导致上面所描述的那种形式的死锁,在那种死锁中,所有线程都被一些任务所占用,这些任务依次等待排队任务的结果,而这些任务又无法执行,因为所有的线程都很忙。

        (2)在为时间可能很长的操作使用合用的线程时要小心。如果程序必须等待诸如 I/O 完成这样的某个资源,那么请指定最长的等待时间,以及随后是失效还是将任务重新排队以便稍后执行。这样做保证了:通过将某个线程释放给某个可能成功完成的任务,从而将最终取得 某些 进展。

        理解任务。要有效地调整线程池大小,您需要理解正在排队的任务以及它们正在做什么。它们是 CPU 限制的(CPU-bound)吗?它们是 I/O 限制的(I/O-bound)吗?您的答案将影响您如何调整应用程序。如果您有不同的任务类,这些类有着截然不同的特征,那么为不同任务类设置多个工作队 列可能会有意义,这样可以相应地调整每个池。

8、handler的拒绝策略

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

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

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

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

9、常见的几种线程池的特点以及各自的应用场景

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

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

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

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

10、Java 代码怎么创建线程

Java线程面试题合集(含答案)_Tanyboye的博客-CSDN博客_线程面试题

上一篇:线程池


下一篇:Scrapy学习系列(一):网页元素查询CSS Selector和XPath Selector