【Java基础】之进程与线程

进程与线程

  • 1. 线程与进程
    • 1.1 概念
    • 1.2 区别与联系
  • 2. 线程的5种状态和切换
    • 2.1 简单介绍
    • 2.2 状态切换
      • 2.2.1 重点情况
  • 3. 线程中常见的方法
  • 4. 线程池

1. 线程与进程

1.1 概念

进程:资源分配的基本单元,如QQ音乐

线程:资源调度的基本单元,如QQ音乐中的播放功能

1.2 区别与联系

①联系:

线程包含在进程里面,多个线程共享一个进程的内存空间;
进程之间是相互独立的,所以进程之间想要互相通信就得借助一些手段才可以;

②区别: 回答点——>地址空间、开销、并发性、内存、健壮性
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。

地址空间

  • 进程之间各自独立,而多个线程之间是共享进程的地址空间;
  • 线程有自己堆栈和局部变量;

开销

  • 进程的上下文切换时间开销消耗资源大,效率差;
  • 线程由于共享一个地址空间,所以线程之间的切换非常快;

并发性

  • 进程的并发性低;
  • 线程的并发性高;

内存:

  • 系统在运行的时候会为每个进程分配不同的内存空间;
  • 而对线程而言,除了 CPU 外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源;

健壮性

  • 一个进程崩溃后,在保护模式下不会对其他进程产生影响;
  • 但是一个线程崩溃整个进程都会死掉。所以多进程要比多线程健壮;

其他:

  • 每个独立的进程有一个程序运行的入口、顺序执行序列和程序的出口
  • 但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制;

2. 线程的5种状态和切换

线程的生命周期一共分为五个部分,分别是:新建,就绪,运行,阻塞,死亡

2.1 简单介绍

  • 新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()
  • 就绪状态(Runnable): 此时线程正在就绪队列中排队等候得到CPU资源;(线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。)处于就绪状态的线程,随时可能被CPU调度执行。
  • 运行状态(Running): 线程获得CPU资源正在执行,此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。需要注意的是,线程只能从就绪状态进入到运行状态。
  • 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程重新进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:线程阻塞态的具体分类
    • (01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成;
    • (02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
    • (03) 其他阻塞 – 通过调用线程的sleep()join()发出了I/O请求时,线程会进入到阻塞状态;
      sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态
  • 死亡状态(Dead): 当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
    • ​ 自然终止:正常运行run()方法后终止
    • ​ 异常终止:调用stop()方法让一个线程终止运行,该线程结束生命周期。

2.2 状态切换

【Java基础】之进程与线程_第1张图片注意:线程只能从就绪态运行态

2.2.1 重点情况

运行——>阻塞

  • 调用wait()方法,等待某事件发生(等待阻塞);
  • 获取synchronized锁失败,(被其他线程正在使用)(同步阻塞);
  • 发生I/O请求(等待用户输入)、调用sleep()或join()方法(其他阻塞)

阻塞——>就绪

  • sleep()、join()等待线程终止或者超时;
  • I/O处理完毕时,线程重新转入就绪状态。

3. 线程中常见的方法

请大家看这篇博客:线程中常见的方法

4. 线程池

  • 概念:一种多线程的处理形式,管理多个线程;

  • 主要思想:在进程开始时创建一定数量的线程,并加到池中以等待工作。当服务器收到请求时,它会唤醒池内的一个线程(如果有可用线程),并将需要服务的请求传递给它。一旦线程完成了服务,它会返回到池中再等待工作。如果池内没有可用线程,那么服务器会等待,直到有空线程为止。

  • 目的减少资源的消耗,提高对资源的利用率

    解释
    java线程的创建非常昂贵,需要JVM和OS(操作系统)互相配合完成大量的工作。而java高并发频繁的创建和销毁线程的操作是非常低效的,如何降低java线程的创建成本,就必须要使用到线程池。

  • 使用线程池的优点

    • 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
    • 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
    • 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
  • 线程池的七个参数

    • corePoolSize:核心线程数,线程池正常情况下保持的线程数,大户人家“长工”的数量
    • maximumPoolSize:最大线程数,当线程池繁忙时最多可以拥有的线程数,大户人家“长工”+“短工”的总数量。
    • keepAliveTime:空闲线程存活时间,没有活之后“短工”可以生存的最大时间。
    • TimeUnit:时间单位,配合参数 keepAliveTime一起使用,用于描述参数 keepAliveTime的时间单位。
    • BlockingQueue:线程池的任务队列,用于保存线程池待执行任务的容器。
    • ThreadFactory:线程工厂,用于创建线程池中线程的工厂方法,通过它可以设置线程的命名规则、优先级和线程类型。
    • RejectedExecutionHandler:拒绝策略,当任务量超过线程池可以保存的最大任务数时,执行的策略。

参考博客:线程池详解:线程池概念以及架构 (baidu.com)

你可能感兴趣的:(JAVA--基础学习,java,jvm,java-ee,spring,spring,boot,后端,mysql)