【多线程】线程是什么?多线程为什么?怎么做?通俗易懂讲解多线程

一、线程是什么?

先搞清楚两个概念
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)线程是一个动态执行的过程,它也有一个从产生到死亡的过程。

下图显示了一个线程完整的生命周期。
在这里插入图片描述

  • 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
  • 就绪状态: 当线程对象调用了 start() 方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
  • 运行状态: 如果就绪状态的线程获取 CPU 资源,就可以执行 run() ,此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
  • 阻塞状态: 如果一个线程执行了 sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
    • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
    • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
    • 其他阻塞:通过调用线程的 sleep()join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
  • 死亡状态: 一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

多线程是指在一个程序中同时执行多个线程,每个线程独立运行,有自己的执行流和栈。多线程的目的是为了提高程序的执行效率和资源利用率,允许程序同时处理多个任务。

多线程就好比是一家餐馆有多个服务员同时为客人服务。
比如,你在餐馆里吃饭,服务员A正在为你点菜,服务员B却正在给其他客人上菜,服务员C则在收拾餐桌。这些服务员在同一家餐馆里协同工作,但各自负责不同的任务。
在计算机中,多线程也是类似的概念。计算机的中央处理器(CPU)可以同时执行多个线程,就像一家餐馆可以同时有多个服务员在工作一样。

二、为什么要有多线程?

  • 提高程序的响应性: 在单线程程序中,如果一个任务阻塞了,整个程序都会停滞。多线程可以使得其他线程继续执行,提高程序的响应性,特别对于需要用户交互的应用更为重要。
  • 提高程序的并发性: 多线程允许多个任务并发执行,充分利用多核处理器,提高系统的吞吐量。
  • 简化程序设计: 复杂的任务可以分解成多个独立的线程,使得程序的设计更为简洁和灵活。
  • 提高资源利用率: 现代计算机通常具有多核处理器,多线程可以充分利用这些处理器资源。

提高效率: 就像在餐馆里,多个服务员同时为不同的客人服务,可以更快地完成任务。
提高响应速度: 如果只有一个服务员,客人可能需要等待很长时间才能被服务。多个服务员可以同时为不同客人提供服务,提高了服务的响应速度。
更好地利用资源: 多线程可以更好地利用计算机的多核处理器,使计算机的性能得到更充分的发挥。

三、多线程的实现方式:

在Java中,实现多线程有两种主要方式:

1、继承 Thread 类:

创建一个类继承自 Thread 类,并重写 run 方法,然后创建该类的实例并调用 start 方法启动线程。示例代码如下:

class MyThread extends Thread {
    public void run() {
        // 线程执行的代码
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

2、实现 Runnable 接口:

创建一个类实现 Runnable 接口,重写 run 方法,然后创建该类的实例,将其作为参数传递给 Thread 类的构造函数,最后调用 start 方法启动线程。示例代码如下:

class MyRunnable implements Runnable {
    public void run() {
        // 线程执行的代码
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

这两种方式都允许程序员创建并发执行的线程,但一般来说,推荐使用实现 Runnable 接口的方式,因为这样可以避免类的单继承限制。在实际开发中,还可以使用线程池、Callable 和 Future 接口等更高级的多线程工具。

四、多线程安全

详情参考【多线程】多线程安全,为什么不安全,要怎么做保证其安全,实例
持续更新中,动动小手,点点关注,后续更精彩!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值