目录
进程与线程
进程
什么是进程?
进程是操作系统对一个正在运行的程序的一种抽象,也可以把进程看做程序的依次运行过程;同时,在操作系统内部,进程是操作系统进行资源(内存、网络、硬盘)分配的基本单位.
进程管理
系统管理进程首先会创建一个进程的pcb结构体(用于描述进程信息),包括:
①pid:标识进程的身份(类似于数据库的主键)
②状态:包括运行、阻塞等等
③内存指针:进程内存地址
④资源清单:io设备、硬盘文件
⑤调度信息
之后把多个进程pcb组织起来(通过一定的数据结构组织相关的信息)
进程的状态
· 并发:一个cpu以时间片轮转调度的方式,执行多个进程,使我们看起来像是在同时执行
· 并行:多个cpu在一个时间点,同时执行多个进程
线程
什么是线程?
线程是操作系统能够进行运算调度的最小单位,被包含在进程中,是进程中的实际运作单位.
一个线程就是一个“执行流”.每个线程之间都可以按照顺序执行自己的代码.多个线程之间“同时”执行着多份代码.
为什么要有线程?
①创建线程比创建进程快
②销毁线程比销毁进程快
③调度线程比调度进程快
④“并发编程”成为“刚需”
线程的实现方式
①内核线程:Java中的线程是基于内核线程的轻量级实现(即相比进程创建更快、小会更快、调度更快)
②用户线程:由程序自己来实现的线程,包括线程调度等等.
进程与线程的关系
①多个进程的内存是隔离开的,而一个进程中的多个线程,可以共享内存
②进程是包含线程的.每个进程至少有一个线程,即主线程
③进程是系统分配资源的最小单位;线程是系统调度cpu执行的最小单位
④线程的创建、销毁代价比进程小(状态转换进程的开销大于线程)
⑤线程(有bug)可能会造成整个进程挂掉,而进程间是独立运行的(可能存在进程通信).
Java线程和操作系统线程的关系
线程是操作系统中的概念.操作系统内核实现了线程这样的机制,并且对用户层提供了一些API供用户使用(例如:Linux的pthread库)
Java标准库中Thread类可以视为是对操作系统提供的API进行了进一步的抽象和封装.
多线程的优点和缺陷
· 优点
①充分利用cpu资源,提高执行效率
②io等阻塞时可以同时接受输入
· 缺陷
①线程的创建/销毁也具有一定的系统开销,所以一般用于执行耗时比较长的任务
②多线程的使用会增加编码的复杂程度.
三种方式创建线程
三种创建线程的方式其实本质上只有一种方法,就是new Thread类 对象,new Runnable只是一个任务的定义和描述,最终还是需要new Thread.
继承Thread
自定义一个类继承Thread
首先创建一个内部类来继承Thread类,再重写run方法,定义要执行的任务代码即可.
public class InheritThread {
//1、继承Thread类 2、重写run方法(定义要执行的任务代码)
private static class MyThread extends Thread {
@Override
public void run() {
System.out.println("myThread run");
}
}
public static void main(String[] args) {
//创建一个线程
MyThread myThread = new MyThread();
//运行一个线程
myThread.start();
}
}
使用匿名内部类
除了定义一个类来继承外,也可以使用匿名内部类的方式来创建线程
public class InheritThread {
public static void main(String[] args) {
Thread t = new Thread() {//属于继承Thread但没有名称的子类
@Override
public void run() {
System.out.println("匿名内部类 run");
}
};
t.start();
}
}
实现Runnable接口
自定义一个类来实现Runnable接口
首先自定义一个类来实现接口,再利用Thread类实例化线程即可
public class AchieveRunnable {
private static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("MyRunnable run");
}
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
匿名内部类实现
匿名内部类的实现有两种写法,一种是先实例化对象,再将其利用Thread类的构造方法来实例化线程,另一种是将匿名内部类对象直接写在构造方法的参数上.
public class AchieveRunnable {
public static void main(String[] args) {
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类run");
}
};
Thread t = new Thread(r1);
//把匿名内部类对象直接写在构造方法的参数上
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类t1run");
}
});
t.start();
t1.start();
}
实现Callable接口
该方法暂时还未学习,后面学习后会补上.