java学习笔记(14) - 进程与线程(1)
进程
- 进程(
process
) 是计算机中程序的一次运行活动,是系统进行资源分配和调度的基本单位(是程序的一次执行过程,是系统运行程序的基本单位),是操作系统结构的基础。进程可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如网易云音乐、360 安全卫士等)
线程
- 线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源。(拥有自己的栈),线程好比做工厂里面的流水线,如果一个工厂里面只有一条流水线,那么这个工厂的效率就必然会非常的底下,如果由多条流水线那么这个工厂的效率就会非常的高,这就是多线程的意义所在
线程和进程的关系:
- 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(通常说的主线程)。
- 系统将资源分配给进程,同一进程的所有线程共享该进程的所有资源。
- 线程在执行过程中,需要协作同步(生产者消费者)。不同进程的线程间要利用消息通信的办法实现同步。
- CPU是分给线程,即真正在CPU上运行的是线程。
创建线程
package Chapter08; |
线程的生命周期
Java
语言中线程有六种状态,分别是:NEW
初始状态- 创建一个线程对象后,该线程对象就处于新建状态,此时它不能运行,与其他Java对象一样,仅仅由Java虚拟机为其分配了内存,没有表现出任何线程的动态特征。
RUNNABLE
可运行状态/运行状态- 当线程对象调用了
start()
方法后,该线程就进入就绪状态。处于就绪状态的线程位于线程队列中,此时它只是具备了运行的条件,能否获得CPU
的使用权并开始运行,还需要等待系统的调度。 - 如果处于就绪状态的线程获得了CPU的使用权,并开始执行
run()
方法中的线程执行体,则该线程处于运行状态。一个线程启动后,它可能不会一直处于运行状态,当运行状态的线程使用完系统分配的时间后,系统就会剥夺该线程占用的CPU资源,让其他线程获得执行的机会。需要注意的是,只有处于就绪状态的线程才可能转换到运行状态。
- 当线程对象调用了
BLOCKED
阻塞状态- 一个正在执行的线程在某些特殊情况下,如被人为挂起或执行耗时的输入/输出操作时,会让出CPU的使用权并暂时中止自己的执行,进人阻塞状态。线程进人阻塞状态后,就不能进入排队队列。只有当引起阻塞的原因被消除后,线程才可以转入就绪状态。
WAITING
无时限等待- 休眠态:一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入
Waiting
状态。进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify
或者notifyAll
方法才能够唤醒。
- 休眠态:一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入
TIMED_WAITING
有时限等待- 指定时间休眠态:基本同
WAITING
状态,多了个超时参数,调用对应方法时线程将进入TIMED_WAITING
状态,这一状态将一直保持到超时期满或者接收到唤醒通知,带有超时参数的常用方法有Thread.sleep
、锁对象.wait()
。
- 指定时间休眠态:基本同
TERMINATED
终止状态- 如果线程调用
stop()
方法或run()
方法正常执行完毕,或者线程抛出一个未捕获的异常(Exception
)错误(Error
),线程就进入死亡状态。一旦进入死亡状态,线程将不再拥有运行的资格,也不能再转换到其他状态。
- 如果线程调用
线程的执行方式:同步异步(Synchronize
, Asynchronize
)
- 可以理解为
js
中的同步与异步操作
package Chapter08; |
使用线程池创建多线程
- 使用线程池创建多线程的方式,也是我们开发中最常用的方式,在多线程编程中,频繁地创建和销毁线程是一种比较消耗资源的操作。而线程池可以在程序启动时就创建一定数量的线程,并重复使用它们来处理任务。这样可以避免线程频繁创建和销毁的开销,提高了程序的执行效率。同时,线程池还可以控制线程的数量,避免线程过多导致资源耗尽或线程过少导致任务处理速度过慢。因此,使用线程池可以更好地平衡系统的负载,提高程序的性能和响应速度。
使用线程池的好处
- 背景:经常创建和销毁、使用最特别大的资源,比如并发情况下的线程,对性能影响很大。
- 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毀、实现重复利用。类似生活中的公共交通工具。
线程池的各个参数详细介绍
corePoolSize
(核心线程数):corePoolSize
表示线程池中的核心线程数量,即线程池中始终保持的活动线程数量。如果当前线程池中的线程数量小于核心线程数,会直接创建新的线程来执行任务。
maximumPoolSize
(最大线程数):maximumPoolSize
表示线程池中允许的最大线程数量。如果当前线程池中的线程数量大于等于核心线程数,但任务队列未满,任务会被放入队列中等待执行。如果任务队列已满,但当前线程池中的线程数量小于最大线程数,会创建新的线程来执行任务。
keepAliveTime
(线程空闲时间) :keepAliveTime
表示线程空闲时的存活时间。如果线程空闲时间超过keepAliveTime
,且线程池中的线程数量大于核心线程数,多余的线程会被销毁,以减少资源消耗。
unit
(时间单位):unit
是keepAliveTime
的时间单位,可以是秒、毫秒、微秒等。通过合理设置keepAliveTime
和unit
,可以控制线程空闲时间的精度。
workQueue
(任务队列):workQueue
是用于存放待执行任务的队列。线程池中的线程会从任务队列中获取任务并执行。常用的任务队列有ArrayBlockingQueue
、LinkedBlockingQueue
、SynchronousQueue
等。
- threadFactory(线程工厂):
threadFactory
用于创建新的线程对象。通过实现ThreadFactory
接口,可以自定义线程的创建方式。例如,可以设置线程的名称、优先级等。
- …
// 使用线程池创建多线程 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0许可协议。转载请注明来自 肥林の仓库