目录
[一. 什么是线程](#一. 什么是线程)
[二. 线程与进程的区别](#二. 线程与进程的区别)
[三. 多线程](#三. 多线程)
[3.1 创建线程](#3.1 创建线程)
[3.1.1 方法1:继承Thread类](#3.1.1 方法1:继承Thread类)
[3.1.2 方法2:实现Runnable接口](#3.1.2 方法2:实现Runnable接口)
[3.1.3 方法3:匿名内部类创建Thread子类对象](#3.1.3 方法3:匿名内部类创建Thread子类对象)
[3.1.4 方法4:匿名内部类创建Runnable子类对象](#3.1.4 方法4:匿名内部类创建Runnable子类对象)
[3.1.5 方法5:lambda创建Runnable子类对象【推荐】](#3.1.5 方法5:lambda创建Runnable子类对象【推荐】)
[3.2 观察线程](#3.2 观察线程)
[3.2.2 使用Java的调试器](#3.2.2 使用Java的调试器)
一. 什么是线程
- 线程(Thread)是操作系统进行任务调度和执行的基本单位,它隶属于进程,是进程内部可独立运行的"子任务单元"。
- 线程也叫轻量级进程。(相较于进程,创建线程不需要申请更多的资源)
- 进程包含了线程。
- 一个线程就是一个"执行流",多个线程之间可以同时执行"多份"代码。
二. 线程与进程的区别
- 进程是包含线程的,一个进程至少包含一个线程(称为主线程).
- 进程与进程之间不共享资源(内存空间),而在同一个进程中的线程之间共享资源(内存空间).
- 进程是操作系统分配资源的基本条件.
- 线程是操作系统调度执行的基本条件.
- 进程与进程之间不会相互影响,而同一个进程中的线程可能会相互影响(多线程编程中,多个线程可能会操作同一数据,这样会产生冲突,导致程序出现bug----线程安全问题)
注意:
- 增加线程的数量确实会提高代码的效率,但是当线程的数量提升超过一个度,效率不一定会提升,反而可能会降低(CPU的核心数是有限的,调度开销也会影响执行效率)
- Java生态中不鼓励使用多进程编程,非常鼓励多线程
三. 多线程
- 线程是操作系统中的概念,对于多线程的相关操作,操作系统提供了对应的API(类/方法)
- 每个线程都是一个独立的"执行流"
- 多个线程是"并发"执行的
3.1 创建线程
3.1.1 方法1:继承Thread类
- 继承Thread类
- 创建MyThread类的实例
- 重写父类(Thread类)的 run()方法
- 调用start方法启用线程
java
public class MyThread extends Thread{
@Override
public void run() {
while (true){
System.out.println("MyThread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Dom {
public static void main(String[] args) {
MyThread r=new MyThread();//Thread r=new MyThread();
r.start();
while (true)
{
System.out.println("hi");
}
}
}
运行代码如下:

注意:
- 我们要执行 r 中的 run 方法时,不是直接调用的 r 的 run()方法,而是调用的 r.start() (调用Thread类的start()方法,该方法执行时会调用操作系统API在系统内部建立一个线程,当线程建立好后,就会自动执行上面重写的run方法)
- main方法自身也对应一个线程(操作系统自动创建),也称为主线程(注意:多线程编译中不存在父/子线程的说法)
- 为防止运行循环时过快,CPU达到极限,我们可以写一个****Thread.sleep()方法(Thread类的一个静态方法),让线程陷入阻塞状态,降低CPU的消耗
- 多线程的调度是由操作系统负责的,操作系统对线程的调度可以认为时"随机"的
问:r.run( ) 与 r.start( ) 的区别:
使用 r.run( ) 时就不存在多线程,即一个执行流,就会导致先执行r.run( ),再执行后面的代码---单线程
3.1.2 方法2:实现Runnable接口
- 实现Runnable接口
- 重写run方法
- 创建MyRunnable实例对象
- 创建Thread类实例对象,调用Thread类的构造方法,将MyRunnable实例对象作为参数
java
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("MyRunnable");
}
}
public class text {
public static void main(String[] args) {
MyRunnable r=new MyRunnable();
Thread t=new Thread(r);
t.start();
System.out.println("hi");
}
}
注意:
- Runnable接口本身不能直接创建线程,需要借助Thread类来实现
- Runnable自身一般不会单独执行,要搭配"载体"
- 将MyRunnable实例对象作为参数后,调用start方法时实际是执行的MyRunnable中重写的run方法
3.1.3 方法3:匿名内部类创建Thread子类对象
- 创建Thread类的子类(没有名字-匿名)
- 重写 run()方法
- 创建Thread的子类的实例,并且使用t引用指向
java
public class text {
public static void main(String[] args) {
Thread r=new Thread(){
@Override
public void run() {
System.out.println("创建新线程");
}
};
r.start();
}
}
记住:调用start()才是真正的创建线程
3.1.4 方法4:匿名内部类创建Runnable子类对象
java
Thread t=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("创建新线程");
}
});
t.start();
}
3.1.5 方法5:lambda创建Runnable子类对象【推荐】
java
Thread m=new Thread(()->{
System.out.println("创建新线程");
});
m.start();
- () -> {... } 是 Lambda 表达式, () 表示 run 方法没有参数, {... } 内是 run 方法的具体实现逻辑,这里通过循环打印信息模拟线程任务。 - 创建 Thread 对象时,将 Lambda 表达式传入, Thread 会在启动后执行该 Lambda 表达式所代表的 run 方法逻辑。 - 调用 thread.start() 启动线程,线程进入就绪状态,等待 CPU 调度执行,同时主线程继续执行自己的逻辑,实现多线程并发。
3.2 观察线程
3.2.1使用jconsole命令观察线程




3.2.2 使用Java的调试器
