文章目录
进程
进程是资源分配的基本单位
进程的创建,销毁,调度都是比较消耗资源与时间的操作
如何管理进程?
- 先使用
PCB
进行描述
- 再通过
双向链表
进行组织
PCB是什么?
Process Control Block的缩写,是描述进程信息的庞大结构体。
包含:
- pid(进程标识符)
- 内存指针(进程持有的内存资源)
- 文件描述符表(进程持有的硬盘资源)
- 状态
- 优先级
- 上下文(进程离开CPU前保存现场,将各种寄存器的信息记录到内存中的信息)
- 记账信息(记录当前进程占用CPU多久了)
线程
线程是调度执行的基本单位
线程也叫做“轻量级进程”
线程不能独立存在,而是要依附于进程(进程包含一个或多个线程)
线程比进程效率高的根本原因是创建线程不需要频繁地申请资源
,一个进程中的多个线程共享一份内存空间和资源
区别
- 多个进程之间相互独立,但多个线程之间耦合性较高。
- 进程的并发性低,线程的并发性高。
- 进程创建、销毁、调度的开销大,线程的开销小
联系
- 进程中可以包含一个线程,也可以包含多个线程,但不能一个都没有。
- 线程共享进程的内存空间和资源。
- 他们都可用于多任务的并发执行。
进程编程方式
继承Thread
代码:
package Demo1;
public class MyThread extends Thread{
@Override
public void run() {
while (true) {
System.out.println("This is thread1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
// 注意调用
public class Main {
public static void main(String[] args) {
// 使用向上转型
Thread t = new MyThread();
t.start();
// 测试main线程
while (true) {
System.out.println("This is main thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
实现Runnable接口(与继承Thread的区别就是:解耦合)
大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类(Thread)创建子类。
- 对比
继承自Thread类
和实现Runnable接口
两种方法:
- 继承自Thread类,这个Thread类中的this代表
当前的进程
- 实现Runnable接口,这个Thread类中的this代表
MyRunnable的引用
,当前进程的标识方法为:Thread.currentThread()
package Demo1;
public class MyRunnable implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("This is thread2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
// 注意调用
package Demo1;
public class Main {
public static void main(String[] args) {
// Runnable接口与Thread不同,需要使用Thread的构造函数
Runnable runnable = new MyRunnable();
Thread t = new Thread(runnable);
t.start();
// 测试main线程
while (true) {
System.out.println("This is main thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
继承Thread使用匿名内部类
package Demo2;
public class Main {
public static void main(String[] args) throws InterruptedException {
// 注意匿名内部类的语法,先小括号,外边写内部类
Thread t = new Thread(){
@Override
public void run() {
while (true) {
System.out.println("This is thread3.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
};
t.start();
while (true) {
System.out.println("This is main thread.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
实现Runnable接口并使用匿名内部类
package Demo2;
public class Main {
public static void main(String[] args) throws InterruptedException {
// 注意匿名内部类的语法,先小括号,外边写内部类
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("This is thread4.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
};// 注意分号
// 写法2
/*Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("This is thread4.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
});*/
Thread t = new Thread(runnable);
t.start();
while (true) {
System.out.println("This is main thread.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
lambda 表达式
package Demo2;
public class Main {
public static void main(String[] args) throws InterruptedException {
// 使用lamda表达式不需要进行重写run()
Thread t = new Thread(() -> {
while (true) {
System.out.println("This is thread5.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t.start();
while (true) {
System.out.println("This is main thread.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}