Java 多线程(一):多线程基础详解

落日映苍穹つ 2021-09-14 06:28 649阅读 0赞

多线程概述

  • 多线程是指一个进程(执行中的程序)同时运行多个线程(进程中负责程序执行的执行单元),多线程可以协作完成进程工作,其目的是更好的利用 CPU 资源

并发与并行

  • 并行:多核多 CPU 或多机器处理同一段处理逻辑的时候,同一时刻多个执行流共同执行
  • 并发:是指通过 CPU 的调度算法,使用户感觉像是再同时处理多个任务,但同一时刻只有一个执行流占用 CPU 执行,即使多核多 CPU 的环境下还是会使用并发,以提高处理效率,主要的调度算法有:

    • 分时调度:每个线程轮流获取 CPU 使用权,各个线程平均 CPU 时间片
    • 抢占式调度:Java 虚拟机使用该调度模型,它会根据线程优先级,先调度优先级高的线程,若线程优先级相同则随机选取线程执行

9434708-5762bd5fdf47ba4c..png

并发与并行

线程终止的四种方式

  • run() 方法执行结束后自然终止
  • 使用 stop() 方法终止
  • 使用 volatile 标志位(外部控制的自然死亡)
  • 使用 interrupt() 方法中断运行状态和阻塞状态线程,interrupt() 方法会改变中断状态,但如果不是在阻塞状态则不会抛出异常,通过 isInterrupt 来作为中断标志推出循环
  • 注意:当线程抛出一个未被捕获的异常或错误时,线程会异常终止

守护线程

  • 守护线程也称为后台线程,在通过 start() 方法调用前先调用 setDeamon(true) 将线程设置为守护线程
  • 守护线程会在所有前台线程死亡后由 JVM 通知死亡
  • 守护线程最大的应用就是垃圾回收线程,它是一个典型的守护线程

线程状态

9434708-467c3ad9548db4f2

线程状态

  • 新建状态:创建了线程 Thread 对象就进入了新建状态
  • 就绪状态:调用 start() 方法就会为线程分配私有的方法栈,程序计算器资源,如果得到 CPU 资源就会从就绪状态转为运行状态
  • 运行状态:就绪状态得到 CPU 资源就会转为运行状态,执行 run() 方法,当调用 yield() 时线程会让步,从运行状态转到就绪状态,但该过程可能是及其短暂的,如果当前线程拥有较高优先级,即使让步后还是会进入运行状态
  • 阻塞状态:会导致阻塞状态的方法主要有:sleep()、wait()、join()、等待获取锁、等待 I/O 等情况,在这些情况被处理后就会转为就绪状态,等待调度
  • 终止状态:上述所说的四种线程终止

基本线程类 Thread 与 Runnable 接口、Callable 接口

Thread

  • 继承 Thread 并重写其 run() 方法,通过线程对象的 start() 方法来启动线程

    public class Test {

    1. public static void main(String[] args) {
    2. MyThread thread = new MyThread();
    3. thread.start();
    4. }

    }
    class MyThread extends Thread{

    1. private static int num = 0;
    2. public MyThread(){
    3. num++;
    4. }
    5. @Override
    6. public void run() {
    7. System.out.println("主动创建的第"+num+"个线程");
    8. }

    }

  • 方法描述

    • sleep():等待一段时间,但是不释放锁,时间到后进入就绪状态等待调度
    • wait():让线程进入等待状态,同时释放当前线程所持有的锁,直到其它线程调用此对象 notify() 或 notifyAll() 方法后,当前线程会被唤醒,进入就绪状态,等待调度(注意:wait 方法只能在 synchronized 方法里使用)
    • join():把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程,比如在线程 B 中调用了线程 A 的 join() 方法,直到线程 A 执行完毕后才会继续执行线程 B
    • notify() 与 notifyAll():notify 只会通知一个在等待的对象,而 nofityAll() 会通知所有再等待的对象

Runnable

  • 实现 Runnable 接口需重写 run 方法
  • Runnable 是”任务”,通过实现该接口,定义一个任务,然后将子任务交由 Thread 去执行

    public class Test {

    1. public static void main(String[] args) {
    2. System.out.println("主线程ID:"+Thread.currentThread().getId());
    3. MyRunnable runnable = new MyRunnable();
    4. Thread thread = new Thread(runnable);
    5. thread.start();
    6. }

    }
    class MyRunnable implements Runnable{

    1. public MyRunnable() {
    2. }
    3. @Override
    4. public void run() {
    5. System.out.println("子线程ID:"+Thread.currentThread().getId());
    6. }

    }

Thread 与 Runnable 区别

  • Thread 是线程、而 Runnable 是任务,一个任务可以由多个线程去完成
  • Java 不允许多继承、因此可实现 Runnable 接口在继承其它类

发表评论

表情:
评论列表 (有 0 条评论,649人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java线详解()

    一、概念 1、进程:是指一个内存中运行的应用程序。 每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。 比如,在windows系统中,一个运行的exe就是一

    相关 Java线基础详解

    一、进程和线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)。举例:任务管理器

    相关 () 线基础

    1.进程和线程区别 多进程:在操作系统中能同时运行多个任务(程序)。如电脑: 微信和网易云音乐同时运行 多线程:在同一应用程序中有多个顺序流在执行。如网易云音乐:音乐