1、前言
最近在备战面试,重新开始复习Java体系的知识点,久没有复习发现又生疏了,同时再次学习又有新的感悟,真的是常学常新。为了让自己理解更深入点,记忆久一些,同时以后复习时更方便,自己整理了学习笔记。更多是站在面试者角度来整理,如果哪里有误欢迎留言指正,万分感谢。
2、进程和线程
2.1、进程
进程可以视为程序的一个实例,进程分为系统进程和用户进程。用于完成操作系统的各种功能的进程是系统进程,由用户启动的进程叫用户进程。打开任务管理器看到的进程分割成两部分,应用就是用户进程,后台进程为系统进程。
2.2、线程
线程是进程中的一个实体,是CPU调度和分派的基本单位,必须依赖于进程而存在,比进程更小的、能独立运行的基本单位。线程基本不拥有系统资源,只拥有在运行中必不可少的资源(如程序计数器、一组寄存器和栈)。它有时也被称为轻量级进程(Lightweight Process LWP)。
2.3、二者关系
一个进程可以拥有多个线程,但一个线程必须有一个父进程。线程可与同属一个进程的其他线程共享所有资源。
2.4、进程间的通信
同一台计算机的进程通信称为IPC(Inter-Process communication),不同计算机之间的进程通信被称为RPC(Remote Procedure Call),需要通过网络和遵守共同的协议。比如Dubbo,Spring Cloud微服务。
2.5、常见的面试题
进程间的通信有几种方式?
有6种,分别为管道、信号、消息队列、共享内存、信号量和套接字。
2.5.1、管道
管道有两种:匿名管道(pipe)和命名管道(named pipe)。匿名管道主要用于有亲缘关系的进程间(父子进程)的通信,命名管道包含匿名管道的功能外,还允许非父子进程间的通信。
2.5.2、信号(signal)
信号是在软件层次上对中断机制的一种模拟,是比较复杂的通信方式,用于通知进程有某事件发生。一个进程收到一个信号和处理器收到一个中断请求效果上类似。
2.5.3、消息队列(message queue)
消息队列是消息的链接表,克服了上面两种通信方式信号量有限的缺点。有写权限的进程(生产者)可按规则向消息队列添加消息,有读权限的进程(消费者)可从消息队列中读取消息做业务处理。
2.5.4、共享内存(shared memory)
它使得多个进程可访问同一块内存空间,不同进程可及时看到共享内存中的数据更新。需要依赖比如互斥锁、信号量等同步操作。可以说是最有用的进程间通信方式。
2.5.5、信号量(semaphore)
主要作为进程之间及同一进程的不同线程之间的同步和互斥手段。
2.5.6、套接字(socket)
用于网络中不同机器之间的进程间通信,应用非常广泛。是一种更一般的进程间通信机制。
3、CPU核心数和线程数的关系
同一时刻,一个CPU核心只能运行一个线程,即CPU内核和同时运行的线程数是1:1的关系。但Intel引入超线程技术后,产生逻辑处理器的概念,使核心数与线程数形成1:2的关系。
在Java中提供获取当前CPU核心数(注:逻辑处理器数)的方法:
Runtime.getRuntime().availableProcessors()
获得当前的CPU核心数在并发编程中很重要,因并发编程下的性能优化往往和CPU核心数密切相关。
4、上下文切换(Context switch)
上下文切换是指CPU(中央处理单元)从一个进程到另一进程(线程)的切换。操作系统在多个进程(线程)之间调度,每个线程在使用CPU时要占用资源,比如CPU寄存器和程序计数器。操作系统要保证线程在调度前后可正常执行,于是有了上下文切换的概念。
4.1、名词解释
4.1.1、上下文
上下文是CPU寄存器和程序计数器在任何时间点的内容。
4.1.2、寄存器
寄存器是CPU内部的一小部分非常快的内存(相当于CPU内部缓存和外部较慢的RAM主内存),通过提供对常用值的快速访问来加快计算机程序的执行。
4.1.3、程序计数器
程序计数器是一种专门的寄存器,指示CPU在指令序列中的位置,并保存着正在执行的指令地址或下一条要执行的指令地址,取决于具体的系统。
4.2、执行过程
上下文可更详细描述:内核(操作系统核心)CPU上的进程(线程)执行以下活动:
1.暂停一个进程的处理,并将该进程的CPU状态(即上下文)存储在内存中的某个地方。
2.从内存中获取下一个进程的上下文,并在CPU寄存器中恢复它。
3.返回到程序计数器指示的位置(即返回到进程被中断的代码行)恢复进程。
4.3、总结
以程序员角度来看:上下文切换是方法调用过程中的各种局部变量和资源;以线程角度来看:上下文切换是方法的调用栈中存储的各类信息。
引发上下文切换原因一般包括:线程/进程切换、系统调用等。上下文切换常是计算密集型的,因涉及一系列数据在各种寄存器、缓存中的来回拷贝。就CPU时间而言,一次上下文切换大概需要5000~20000个时钟周期,相对于一个简单指令几个到十几个左右执行时钟周期来说,成本巨大。
5、并行和并发
并发(concurrent):指应用能够交替执行不同的任务。
并行(parallel):指应用能够同时执行不同的任务。
两者区别:前者是交替执行,后者同时执行。当谈论并发时一定要单位时间(即单位时间内并发量是多少?),离开了单位时间没有意义。