目录
1.计算机发展史
2.冯诺依曼体系
运算器:执行具体的CPU指令
控制器:调度的角色,负责告诉CPU执行哪些指令
存储器:寄存器,内存,外存
速度越来越慢,容量越来越大,造假越来越低
输入设备:键盘,鼠标
输出设备:显示器,音箱
计算机最重要的就是CPU,CPU干的活就是执行指令
3.操作系统
操作系统的作用:
1.向上为应用程序提供一个稳定的运行环境
2.向下管理着所有的计算机设置
3.为用户提供一个人机交互界面
4.进程
每一个运行起来的软件,操作系统都会以进程的形式将他管理起来
在操作系统中,每一个进程都被描述成一个进程控制块(PCB)
1.PID(进程编号)
2.内存指针 应用程序申请到的内存中的首地址
3.文件描述符表
一个内核有两个处理器,一个处理器可以运行一个指令
所以单核并不是同时运行的 ,而是以飞速轮动的方式在不同的进程之间来回调度,看似同时运行,但实际上不是
根据优先级来
在一个处理器上横向的轮动称作并发,纵向的多核处理器称作并行
问:什么是并发?什么是并行?
以吃饭和接电话为例:
吃完饭才能接电话,称作串行
吃饭途中放下碗筷去接电话,称作并发
边吃饭边接电话,称作并行
4.进程的优先级(谁使用CPU的频率多)
5.进程的状态
6上下文件信息 7.记账信息
记录了当前进程执行到了那里,下次直接从这里开始即可
5.虚拟内存空间
进程启动之后就会申请内存空间
所以我们提出了虚拟内存地址
6.mmu
7.多线程
1.概念
多线程用来处理一个很复杂或者很大的任务
问:进程和线程的区别?
对于一个进程而言,必然会有一条线程(主线程)
进程是申请系统资源的最小单位
线程CPU调度的最小单位
进程之间互不影响,线程之间可以相互影影响
使用多线程编程的原因 ?
2.多线程可能存在的问题
1.当线程增加到一定程度时,不但没有提高效率,反而会给CPU调度带来负担
在真实程序中,确定线程的数据要经过测试
2.多线程之间资源争抢,会出现一些线程不安全的问题
8.第一个线程程序
1.创建线程方法一继承Thread类
通过JDK给我们提供的API来创建线程
这个线程时Java中的类,不是系统中真正的PCB
1.继承Thread类
2.重写run()方法
让线程执行指定的任务
class MyThread01 extends Thread {
@Override
public void run() {
while (true) {
System.out.println("线程执行的任务");
//休眠
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.调用start()方法执行线程
通知操作系统CPU调度
public class Demo02 {
public static void main(String[] args) {
//创建线程对象
MyThread01 myThread01 = new MyThread01();
myThread01.start();
//
while (true) {
System.out.println("main方法中的线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread.sleep(1000)的意思是保证在1000ms之内这个线程不被调度到CPU上执行
2.第一个线程执行结果
3.创建线程方法二实现Runnable接口并重写run()
public class Demo03 {
public static void main(String[] args) {
//创建Runnable对象
MyRunnable myRunnable = new MyRunnable();
//创建线程传入Runnable对象
Thread thread = new Thread(myRunnable);
thread.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("生产皮包,金币+10010");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4.创建线程方法三通过匿名内部类
public class Demo04 {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("runnable 的线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread() {
@Override
public void run() {
while (true) {
System.out.println("thread 的线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t1.start();
t2.start();
}
}
5.创建线程方法四使用Lambda表达式
public class Demo05 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
System.out.println("lambda 定义的线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
);
t1.start();
}
}
6.创建线程之方法五使用Callable接口
1.JUC
java.util.concurrent 包的简称,JDK1.5之后对多线程的一种实现,这个包下的类都和多线程有关,提供了很多工具类
2.Callable接口
测试实现:
public static void main(String[] args) throws ExecutionException, InterruptedException {
//定义一个线程任务
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += 1;
TimeUnit.SECONDS.sleep(1);
System.out.println("等待一秒");
}
return sum;
}
};
//通过FutureTask类来创建一个对象,这个对象持有callable
FutureTask<Integer> futureTask = new FutureTask<>(callable);
//创建线程并指定任务
Thread thread = new Thread(futureTask);
thread.start();
// 获取线程执行的结果
System.out.println("等待结果...");
Integer res = futureTask.get();
System.out.println(res);
也是描述任务的接口
9.说一说Runnable与Callable的区别?
1.Callable实现的是call方法,Runnable实现的是run方法,但都描述的是任务
2.Callable可以返回一个结果,Runnable不能返回结果
3.Callable可以抛出异常
4.Callable要配合FutureTask一起使用
10.线程有几中创建方式
1.继承Thread类,重写run方法
2.实现Runnable接口,实现run方法
3.实现Callable接口,实现call方法
4.通过线程池来创建线程
11.使用Runnable定义任务的好处
以张三的工厂为例