目录
1.什么是进程
1.1进程控制块抽象
1.2 CPU 分配 —— 进程调度(Process Scheduling)
1.3内存分配 —— 内存管理(Memory Manage)
1.4进程间通信(Inter Process Communication)
2.线程
2.1概念
2.2为什么要有线程
2.3线程和进程的区别
2.4 Java线程和操作系统线程的关系
3.使用Java代码来实现多线程程序
3.1.继承Thread类来实现
3.2实现Runnalbe接口
3.3匿名内部类创建Thread子类对象
3.4匿名内部类创建Runnable类对象
3.5 多线程的优势-增加运行速度
每个应用程序运行于现代操作系统上的时候,操作系统会提供一种抽象,好像系统上只有这个程序在运行,所有的硬件资源都是这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学最重要和最成功的概念之一。
进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位.
计算机内部要管理任何现实事物,都需要将其抽象成一组有关联的、互为一体的数据。在 Java 语言中,我们可以通过类/对象来描述这一特征.
// 以下代码是 Java 代码的伪码形式,重在说明,无法直接运行
class PCB {
// 进程的唯一标识 —— pid;
// 进程关联的程序信息,例如哪个程序,加载到内存中的区域等
// 分配给该资源使用的各个资源
// 进度调度信息
}
这样,每一个 PCB 对象,就代表着一个实实在在运行着的程序,也就是进程。
操作系统再通过这种数据结构,例如线性表、搜索树等将 PCB 对象组织起来,方便管理时进行增删查改的操作.
为了便于讨论和理解,我们大部分的场景下假设是单CPU单核的计算机。
操作系统对CPU资源的分配,采用的是时间模式 —— 不同的进程在不同的时间段去使用 CPU 资源。
操作系统对内存资源的分配,采用的是空间模式 —— 不同进程使用内存中的不同区域,互相之间不会干扰。
如上所述,进程是操作系统进行资源分配的最小单位,这意味着各个进程互相之间是无法感受到对方存在的,这就是操作系统抽象出进程这一概念的初衷,这样便带来了进程之间互相具备”隔离性
(Isolation)“。
但现代的应用,要完成一个复杂的业务需求,往往无法通过一个进程独立完成,总是需要进程和进程进行配合地达到应用的目的,如此,进程之间就需要有进行“信息交换“的需求。进程间通信的需求就应运而生。
目前,主流操作系统提供的进程通信机制有如下:
1. 管道
2. 共享内存
3. 文件
4. 网络
5. 信号量
6. 信号
其中,网络是一种相对特殊的 IPC 机制,它除了支持同主机两个进程间通信,还支持同一网络内部非同一主机上的进程间进行通信.
一个线程就是一个'执行流',每个线程之间都可以按照顺序执行自己的代码,多个线程之间'同时'执行着多份代码
举个例子,比如我现在要去搬家,我一个人忙不过来,喊了张三和李四一起来.然后我们三个人一人负责一件事,我负责搬家电,张三负责开车,李四负责收拾.但是本质上我们三个人是办的搬家这一件事.
此时我们就可以把这种情况称为多线程,将一个大任务分解成不同的小任务,交给不同执行流分别执行,其中张三和李四是我叫来的,所以我一般被称为主线程.
线程是操作系统中的概念. 操作系统内核实现了线程这样的机制, 并且对用户层提供了一些 API 供用户使用(例如 Linux 的 pthread 库).
Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装
package demo;
class MyThread extends Thread{
@Override
public void run() {
while (true){
System.out.println("这是线程运行的代码");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
while (true){
System.out.println("main函数");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
使用Javabin自带的jconsole来观察线程
上图是一个main线程
package demo1;
class MyThread implements Runnable{
@Override
public void run() {
System.out.println("Runable");
}
}
public class Test {
public static void main(String[] args) {
Thread myThread = new Thread(new MyThread());
myThread.start();
}
}
package demo2;
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(){
@Override
public void run() {
System.out.println("匿名内部类创建子类对象");
}
};
}
}
package demo3;
public class Test {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类创建Runnable类对象");
}
};
}
}
3.5lambda表达式创建Runnable子类对象
package demo4;
public class Test {
public static void main(String[] args) {
Thread runnable = new Thread(() -> {
System.out.println("hello");
});
}
}
可以观察多线程在一些场合下是可以提高程序的整体运行效率的。
使用 System.nanoTime() 可以记录当前系统的 纳秒 级时间戳.
serial 串行的完成一系列运算. concurrency 使用两个线程并行的完成同样的运算.