程序的启动过程(如何从程序变为进程)
双击程序进行启动
OS:
1.找到文件,检查文件是否合法
2.创建一个PCB对象-描述
PCB pcb=nnew PCB();
3.为进程分配一个唯一的id
4.把程序文件按照指定格式加载到内存中
5.把PCB对象和之前加载的内容关联。
pcb.pc=pc;pcb.dataZone=dataZone;
6.填充基本的记账信息。
pcb.startAt=System.currentTime();
7.把pcb放到几个相关的的数据结构中
常见的进程切换:
1.有一个更高优先级的进程近来-抢占式OS
2.任务完成
3.每个进程都事先分配好时间片,到达后,切换
4.当前进程正在等待一个外部事件–阻塞
切换:上下文——保护和恢复
上下文:PC 其他寄存器
并发VS并行
并发是假同时
并行是真同时
内核态VS用户态
比如说银行的例子:用哪个户是用户态,银行内部是内核态
操作系统的状态:
新建 就绪 运行 终止 阻塞
进程VS线程
进程是资源分配的最小单位
线程是CPU调度的最小单位
线程的创建比进程创建更轻量级(线程是轻量级进程)
JVM的线程不一定就是OS中的线程,但特性是相似的
对于程序猿,不要关注操作系统的线程
多线程的优势:
1.在某些场景下,建模简单(代码好写)
2.某些场景下,运行速度可以提升
如何创建线程
- Thead类 (线程的描述类)
每一个线程都有一个Thead对象与之一一对应
创建一个Thread对象
1.继承Thread类,覆写run方法
2.实现Runnable方法,覆写run方法
栈: 每个线程都有自己独立的空间
栈里的数据不共享
堆和方法区中的数据是共享的。
JVM结束的条件,不是主线程退出就退出,而是所有费守护线程退出才退出。
调用 Thread对象的interrupt方法,会将对象的interrupt status置为true,是建议性的中断
四个多线程例子:
public class ThreadDemo{
private static class MyThread extends Thread {
@Override
public void run() {
while (true) {
System.out.println("我在 method2 中打印");
// 进程会暂停运行 1 秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static void method2() {
Thread thread = new MyThread();
thread.start();
}
public static void main(String[] args) throws InterruptedException {
method2();
while (true) {
System.out.println("我在 main 中打印");
// 进程会暂停运行 1 秒
Thread.sleep(1000);
}
}
private static void method1() throws InterruptedException {
while (true) {
System.out.println("我在 method1 中打印");
// 进程会暂停运行 1 秒
Thread.sleep(1000);
}
}
}
import java.util.Scanner;
class Fibonacci {
// O(2^n)
public static long calc(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return calc(n - 1) + calc(n - 2);
}
}
}
class FibonacciThread extends Thread {
private int n;
FibonacciThread(int n) {
this.n = n;
}
@Override
public void run() {
long result = Fibonacci.calc(n);
System.out.printf("第 %d 项斐波那契数为: %d%n", n, result);
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入要计算第几项的斐波那契数");
int n = scanner.nextInt();
Thread thread = new FibonacciThread(n);
thread.start();
}
}
}
import java.util.Scanner;
public class ThreadDemo3 {
private static class FibonacciThread2 extends Thread {
private int n;
FibonacciThread2(int n) {
this.n = n;
}
@Override
public void run() {
long result = Fibonacci.calc(n);
System.out.printf("%nfib(%d) = %d%n", n, result);
}
}
public static void main(String[] args) throws InterruptedException {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入:");
int n = scanner.nextInt();
Thread thread = new FibonacciThread2(n);
System.out.print("计算中 ");
thread.start();
while (thread.isAlive()) {
Thread.sleep(1000);
System.out.print(".");
}
}
}
}
public class ThreadDemo4 {
private static final long COUNT = 10_0000;
public static void main(String[] args) throws InterruptedException {
serial(); // 串行
concurrent(); // 并发
}
private static class CalcThread extends Thread {
@Override
public void run() {
int n = 0;
for (long i = 0; i < COUNT; i++) {
n++;
}
}
}
private static void concurrent() throws InterruptedException {
long begin = System.nanoTime();
Thread thread1 = new CalcThread();
thread1.start();
Thread thread2 = new CalcThread();
thread2.start();
int a = 0;
for (long i = 0; i < COUNT; i++) {
a++;
}
thread1.join();
thread2.join();
long end = System.nanoTime();
double s = (end - begin) * 1.0 / 1000 / 1000 / 1000;
System.out.printf("并发模式: 耗时: %.4f%n", s);
}
private static void serial() {
long begin = System.nanoTime();
int a = 0;
for (long i = 0; i < COUNT; i++) {
a++;
}
int b = 0;
for (long i = 0; i < COUNT; i++) {
b++;
}
int c = 0;
for (long i = 0; i < COUNT; i++) {
c++;
}
long end = System.nanoTime();
double s = (end - begin) * 1.0 / 1000 / 1000 / 1000;
System.out.printf("串行模式: 耗时: %.4f%n", s);
}
}