目录
前言
本文为线程的学习笔记,刚开始学习Java,有错误及不完善的地方还请大佬们指出~
1. 基本概念
1.1 进程和线程
-
进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。进程运行后必须到所有非守护线程都结束运行才能结束。
-
线程:一条线程指进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同任务
-
守护线程:又叫精灵线程,在后台自动执行,如JVM的垃圾回收机制。当程序只剩下守护线程时,程序将结束
进程和线程的区别:
区别 | 线程 | 进程 |
---|---|---|
根本区别 | 调度和执行的单位 | 作为资源分配的单位 |
开销 | 同一类线程共享代码和数据空间,线程切换的开销小 | 每个进程都有独立的代码和数据空间,进程切换开销大 |
所处环境 | 同一个应用程序中有多个顺序流同时执行 | 操作系统中能运行多个任务(程序) |
分配内存 | 除CPU外不会为线程分配内存,线程组共享资源 | 系统运行时为每个进程分配不同内存区域 |
1.2 并行和并发
- 并行:两个任务同时运行,需要多核CPU
- 并发:两个任务同时请求运行,而处理器只能接受一个任务,则安排两个任务轮流进行
2. 线程创建
2.1 继承Thread类
- 创建一个继承于Thread类的子类
- 重写Thread类中的run方法:此线程要执行的操作声明在run方法中
- 创建Thread子类的对象
- 调用此对象的start方法启动线程并调用其run方法
例:
package com.thread.create;
/**
* @ClassName: MyThread01
* @PackageName: com.thread.create
* @Description: 方式一:继承Thread类并重写run方法
* @Author: Caroline
* @Date: 2021/9/1 22:42
* @Version: v1.0
*/
public class MyThread01 extends Thread {
/**
* @Description: 重写run方法
* @Param: []
* @Return: [void]
* @Date: 2021/9/1 22:57
*/
@Override
public void run() {
//thread执行时的任务内容:创建线程并输出线程名到控制台
System.out.println(Thread.currentThread().getName());
}
}
package com.thread.test;
import com.thread.create.MyThread01;
import org.junit.Test;
/**
* @ClassName: MyThread01Test
* @PackageName: com.thread.test
* @Description: 继承Thread类方式创建线程测试类
* @Date: 2021/9/1 22:45
* @Version: v1.0
*/
public class MyThread01Test {
/**
* @Description: 测试通过MyThread01类创建两个线程
* @Param: []
* @Return: [void]
* @Date: 2021/9/1 22:58
*/
@Test
public void testCreateThread() {
for (int i = 0; i < 2; i++) {
//new线程对象
Thread thread = new MyThread01();
//启动线程
thread.start();
}
}
}
2.2 实现Runnable接口
- 创建一个实现Runnable接口的类
- 实现Runnable接口中抽象方法:run方法
- 创建Runnable接口实现类的对象
- 将实现类对象作为参数传递到Thread类构造器,创建Thread类对象
- 调用Thread对象start方法启动线程并执行run方法
例:
package com.thread.create;
/**
* @ClassName: MyThread02
* @PackageName: com.thread.create
* @Description: 方式二:实现Runnable接口创建线程
* @Date: 2021/9/2 14:48
* @Version: v1.0
*/
public class MyThread02 implements Runnable {
/**
* @Description: 重写run方法
* @Param: []
* @Return: [void]
* @Date: 2021/9/2 14:48
*/
@Override
public void run() {
//thread执行时的任务内容:创建线程并输出线程名到控制台
System.out.println(Thread.currentThread().getName());
}
}
package com.thread.test;
import com.thread.create.MyThread02;
import org.junit.Test;
/**
* @ClassName: MyThread02Test
* @PackageName: com.thread.test
* @Description: 实现Runnable接口方式创建线程测试类
* @Date: 2021/9/2 14:49
* @Version: v1.0
*/
public class MyThread02Test {
/**
* @Description: 测试通过MyThread02类创建的两个线程
* @Param: []
* @Return: [void]
* @Date: 2021/9/2 14:52
*/
@Test
public void testCreateThread() {
for (int i = 0; i < 2; i++) {
//new线程对象
Thread thread = new Thread(new MyThread02());
//启动线程
thread