什么是进程,什么是线程?
进程:程序执行的一个单元,理解为一项任务,比如window上运行的酷狗音乐、浏览器等执行程序就是一个进程。
线程:线程是比进程更小的执行单元,一个进程有多个线程,多个线程在执行时候,共享一块内存区域。
需要了解的重要概念
并发和并行
并发:多个线程交替执行,也有可能串行执行,不是真正意义上的同时执行
并行:真正意义上的同时执行
单核CPU上,多线程是交替执行的,也就是并发,在多核CPU上,多线程才可能并行。
同步和异步
同步: 调用一个方法后,必须等待这个方法执行完毕,才能接着去执行下一个方法
异步: 不用等待方法返回,就可以去调用另一个方法。例如,异步的一个应用场景就是消息队列,生产者产生消息后不用等待消费者消费,就能直接返回。
高并发
高并发(High Concurrency)是指通过设计保证程序能够并行处理很多请求,是互联网分布式架构中必须考虑的因素之一。
高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。
临界区
是指一种共享资源,在多个线程间共享,每一次只能有一个线程占有,其他线程只能等待。
创建线程的三种方式
虽然前两种用的比较多,但是建议使用第三种方式创建线程,降低系统开销,并且容易管理
- 继承Thread类
- 实现Runnable接口
- 线程池创建
线程调度
什么是线程调度?
线程调度指的是CPU在多线程执行的情况下,执行各个线程的具体细节是怎么样的,是在多个线程间切换执行还是一个线程执行完毕再去执行下一个线程,可以分为下面两种方式,采用哪种方式取决于操作系统。
抢占式线程调度
每个线程的执行时间由系统决定,cpu不会一直执行一个线程,而是会在不同线程之间切换执行,这样就不会因为一个线程阻塞了,其他线程都无法执行。线程的切换和调度很快,所以感觉所有线程是同时执行的。
协同式线程调度
每个线程的执行时间由线程本身决定,一个线程需要多少执行时间,就一直占有多少CPU执行时间,线程执行完毕,才会执行另一个线程,如果线程一直阻塞,后面执行的线程会无法执行。
线程状态
New(新建): 创建后没有启动
Runnable(运行): 包括两种状态:running,Ready ,也就是可能在运行中,也可以是在等待CPU执行
Waiting(无限期等待): 这种状态的线程,不会被分配CPU执行时间,等待其他线程唤醒.
调用没有设置timeout的方法Object.wait(),Thread.join()或者LockSupport.park()方法进入
Time Waiting (限期等待): 也不会被分配CPU时间,系统自动唤醒。
调用
设置timeout的Object.wait(),Thread.sleep(),Thread.join()方法
LockSupport.parkNanos()方法
LockSupport.parkUtil()方法进入
Blocked(阻塞): 等待获取到一个排他锁,在另一个线程释放锁时发生。
Terminated(停止):线程结束执行。
来自: 《深入理解Java虚拟机》12章 4 节
相关的cpu术语和说明
术语 | 描述 |
内存屏障 | 一组处理器指令实现对内存操作的顺序限制 |
缓存行 | 缓存中可以分配的最小存储单位 |
原子操作 | 不可中断的一个或者一组操作 |
缓存行填充 | 当处理器识别到从内存中读取的操作数是可缓存的,处理器读取整个缓存行到适当的缓存中 |
缓存命中 | 如果进行高速缓存行中填充操作的内存位置,仍然是下次处理器访问的位置,处理器从缓存中读取数据而不是内存中 |
写命中 | 当处理器将操作数写入到内存缓存的区域时候,先检查一个缓存的内存地址是否在缓存行中,如果存在一个有效的缓存行,就写入到缓存行中,而不是内存中 |
写缺失 | 一个有效的缓存行写入到不存在的内存区域 |