Java并发编程(一):多线程与并发原理回顾

article/2025/9/16 22:01:37

在这里插入图片描述
今天来聊一聊经典的Java技术,并发编程。并发是程序的灵魂,一个优秀的Java程序一定会支持高并发,并且,并发编程也是面试环节中经常会问到的一个问题,那么今天我们以一道经典的Java面试题回顾一下Java的并发编程。废话不多说,直入正题…
在这里插入图片描述

请你简单讲一下什么是线程?在Java中创建线程有几种方式?Java中的线程有哪些特点?

答:线程是比进程更细致的独立单位,线程是CPU调度与分派的最小单位。在Java中创建线程的方式一共有两种:一种是继承Thread类完成对Thread类的扩展,进而实现线程的创建,另一种是实现Runnable接口。从代码层面来解读就是如下:

// @fntp--Java多线程系列笔记
public class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println(Thread.currentThread().getName() + " 运⾏了");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

然后我们可以在测试方法或者Main方法中进行测试:
请读者不要看不起这不起眼的代码,其实内部蕴含着很深的奥妙。比如这里调用的Start()方法,start()方法从英文翻译的角度字面意思来看,就是启动线程,也就是将调用该方法的线程的当前状态从创建-就绪状态转向运行时状态

// @fntp--Java多线程系列笔记
public static void main(String[] args) {MyThread thread = new MyThread();thread.start();
}

实现Runnable接口方式:

// @fntp--Java多线程系列笔记
public class MyRunnable implements Runnable {@Overridepublic void run() {while (true) {System.out.println(Thread.currentThread().getName() + " 运⾏了");try {Thread.sleep(800);} catch (InterruptedException e) {e.printStackTrace();}}}
}

然后我们可以在测试方法或者Main方法中进行测试:

// @fntp--Java多线程系列笔记
public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start();
}

在Java程序中,不论是并发还是单线程程序,都会存在一个名为主线程Thread对象。在JVM(Java虚拟机)执行Java程序时,Java虚拟机会创建一个Thread来执行Main方法。也就是说,Java中的Main方法在执行的时候,也是以线程的形式存在于Java虚拟机中。
以上描述,值得注意的点是:

  1. Java中任何程序不论并发与否,只要启动Jav程序,那么就必定存在主线程。
  2. Java中的多线程,线程与线程之间共享Java应用程序的所有资源。[1]
  3. Java中线程都具备优先级[2]。
  4. Java中主动创建线程时,可以创建以下两类线程:(1)守护线程(2)非守护线程。
  5. 线程具备六种状态:
    (1)NEW:新建状态。
    (2)RUNNABLE:可运行状态,我不建议称作就绪状态,原因下文会解释。
    (3)BLOCKED:阻塞状态。
    (4)WAITING:等待状态。
    (5)TIMED_WAITING:定时等待状态。
    (6)TERMINATED:终止状态。

[ 1 ] 这里的资源则包括内存,与存在于内存中的文件、对象、变量等资源,线程之间快速⽽简单地共享应用程序的信息。需要注意的是:必须使⽤同步避免线程与线程之间发生数据竞争。
[ 2 ] Java中线程的优先级数值存在一定的范围,优先级数值介于Thread.MIN_PRIORITY(1)与Thread.MAX_PRIORITY(10)之间,默认优先级是Thread.NORM_PRIORITY(5),具体的优先级起不起作用需要关注操作系统对线程优先级的支持,线程的优先级无法一定保证优先级,只能提高优先调度的概率。

以上主要讲解了Java中线程的基本概念,以及线程的创建方式方法,以及线程的五点值得关注的主要性质。对于线程的状态,我以JDK11最新版11.0.13版本作为源码样本,进行详致讲解。如下图所示:这里我们先关注两个点,Thread的内部静态方法getState()方法的用途与返回值。
图1-1
在这里插入图片描述
我们不难发现,Thread内部的State是一个枚举类。线程的状态获取底层是通过jdk.internal.misc.VM.toThreadState()方法进行实现的,该方法需要传入一个Int类型的数据,这个方法的底层实现逻辑如下图:
在这里插入图片描述
一方面,这充分说明了,在Thread类中,线程状态是固定的范围,一共六种状态,上面已做列举。每一种状态使用不同的数值进行表示。将传入的数值与JVMTI_THREAD_STATE常量进行按位与,从而计算按位与的结果。值得一提的是,JVMTI_THREAD_STATE 字段也就是线程状态字段是根据虚拟机在hotspot中实现状态转换时设置的。它的值是根据 JVM-TI 规范中的 GetThreadState () 函数设置的。
在这里插入图片描述
到现在为止,线程的状态获得的底层原理已经有了一个初步的大概,但对于线程的六种状态之间的切换是怎么操作的我们还没有一个明确的答案,接下来,我们一起来看一下线程切换的流程。下图:线程流程图,选图来自CSDN博主【m0_37779570】。
在这里插入图片描述
从这张图中,我们可以清晰的看出线程对象在调用start()方法后进入了RUNNABLE状态,进入RUNNABLE状态并不意味着就能立马执行,而是等待CPU线程调度器进行选择调度,当线程被调度后,才会进入运行中状态,但是如果此时调用了yield()方法,就会让线程重新回到就绪状态。

在线程处于RUNNABLE期间,此时发起阻塞IO操作会导致线程进入BLOCKED状态,当阻塞IO操作结束,又会重新回到RUNNABLE状态,当操作申请锁时,会进入阻塞状态,在获得锁后,又会进入RUNNABLE状态。

当处于RUNNABLE状态的线程调用了wait() 方法后,线程会进入WAITING状态,当被其他对象调用了notify() 或者notifyAll() 方法进行线程唤醒后,又会重新进入RUNNABLE状态,等待CPU调度。

当处于RUNNABLE状态的线程调用了Sleep() 方法后,线程会进入TIMED_WAITING状态,执行结束后又会及进入RUNNABLE状态。

特别注意!在给定的单位时间内,线程只能处于一个状态。

这里所涉及的所有线程状态,均来自于JVM-java虚拟机规范中的线程状态,不能类比操作系统的线程状态。

特别注意这里的RUNNABLE,我为什么不建议将RUNNABLE状态称之为就绪状态?因为RUNNABLE细分的话还包括就绪状态与执行中状态,这个RUNNABLE要从字面意思去理解更好理解一些,RUNNABLE代表着线程处于可执行状态,但是可执行并不代表着线程就处于执行状态,线程是否真正处于执行状态是取决于CPU的时间片与其他资源分配的。简而言之,就是说,线程处于就绪状态后,需要等待CPU分配系统资源才能进入RUNNING运行中状态;在处于RUNNABLE状态后,如果未获得CPU分配的系统资源,那么就会处于READY就绪状态。


http://chatgpt.dhexx.cn/article/i7G59w5w.shtml

相关文章

java并发编程的艺术和并发编程这一篇就够了

java并发编程的艺术(精华提炼) 通常我们在使用编发编程时,主要目的是为了程序能够更快的处理,但是并不是说更多的线程就一定能够让程序变得足够快,有时候太多的线程反而消耗了更多的资源,反而让程序执行得更缓慢 一.CPU的上下文切换 就算是单核CPU是能够处理多线程任务的,它只…

JAVA并发编程总结

一、基础知识 1.1 线程安全 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。 CAP理论 原子性 我们把一个或者多个操作在CPU执行的过程中不被中断的特性称为原子性. 可见性 当一个线程修改了对象状态后&#xf…

Java并发:整理自《Java并发编程实战》和《Java并发编程的艺术》

声明:Java并发的内容是自己阅读《Java并发编程实战》和《Java并发编程的艺术》整理来的。 图文并茂请戳 思维导图下载请戳 目录 (1)基础概念 (2)线程 (3)锁 (4)同步器 (5)并发容器和框架 (6)Java并发工具类 (7)原子操作类 (8)Executor框架(执行机制) (9)…

Java并发编程的艺术-并发编程基础

Java从诞生开始就明智地选择了内置对多线程的支持,这使得Java语言相比同一时期的其他语言具有明显的优势。线程作为操作系统调度的最小单元,多个线程能够同时执行,这将显著提升程序性能,在多核环境中表现得更加明显。但是&#xf…

java并发编程(下篇)

java里的阻塞队列 ArrayBlockingQueue 数组结构组成的有界阻塞队列 LinkedBlockingQeque 链表结构的无界阻塞队列 PriorityBlockingQueue 支持优先级排序的无界阻塞队列 DelayQueue 使用优先级队列实现的无界阻塞队列 LinkedBlockingDeque 链表结构组成的双向队列 并发工具…

Java并发编程之美——第一章 Java并发编程基础

文章目录 Time 2021-12-26——Hireek什么是线程线程的等待和通知等待线程终止的join方法让线程睡眠的sleep方法让出CPU执行权的yield方法线程中断demo 线程上下文切换线程死锁什么是死锁如何避免死锁 用户线程与守护线程ThreadLocalintroduction,下文只阐述重要的se…

Java并发编程入门这一篇就够了(文章很长,但很好哦)

Java并发编程入门这一篇就够了 一、进程与线程1. 进程2. 线程3. 二者对比 二、并行与并发三、Java线程1. 创建和运行线程2. 线程运行原理3. 常见方法4. 常用方法详解及异同区分5. 两阶段终止模式(使得线程优雅的退出)6.主线程与守护线程7. 线程五种状态8…

Java并发编程之Java线程

文章目录 前言01、线程简介02、线程池03、线程间通信总结 前言 记录一下Java并发编程的知识点。有部分内容是借鉴《Java并发编程的艺术》这本书的。本次先介绍一下线程。 01、线程简介 进程和线程的区别 进程:当一个程序被运行,即把程序的代码从磁盘加载…

Java并发编程的艺术

1、并发编程的挑战 1、上下文切换 CPU通过给每个线程分配CPU时间片来实现多线程机制。时间片是CPU分配给各个线程的时间,这个时间非常短,一般是几十毫秒。 CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务…

Java并发编程简介

并发编程简介 1. 什么是并发编程 所谓并发编程是指在一台处理器上“同时”处理多个任务。并发是在在同一实体上的多个事件。多个事件在同一时间间隔发生。 并发编程 ①从程序设计的角度来讲,是希望通过某些机制让计算机可以在一个时间段内,执行多个任务…

【java】Java并发编程系列-基础知识(非常详细哦)

文章目录 一、Java并发编程基础1.1 并发编程基本概念1.1.1原⼦性1.1.2 可⻅性1.1.3 有序性 二、内存模型三、重排序四、内存屏障五、总结 一、Java并发编程基础 主要讲解Java的并发编程的基础知识,包括原⼦性、可⻅性、有序性,以及内存模型JMM&#xff…

理解Java并发编程

计算机基础 要想理解Java多线程,一定离不开计算机组成原理和操作系统,因为,java的多线程是JVM虚拟机调用操作系统的线程来实现的 /*Thread.start() 方法中调用了原生的start0()方法 */ public synchronized void start() {if (threadStatus…

【并发编程】JAVA并发编程面试题合集

1.在Java中守护线程和本地线程的区别? Java中的线程分为两种:守护线程(Daemon)和用户线程(User)任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(boolean);true表…

Java并发编程概述

在学习并发编程之前,我们需要稍微回顾以下线程相关知识: 线程基本概念 程序:静态的代码,存储在硬盘中 进程:运行中的程序,被加载在内存中,是操作系统分配内存的基本单位 线程:是cpu执…

java并发编程(并发编程的三个问题)

什么是并发编程? 首先我们要知道什么是并发? 什么是并行? 并行: 多件事情在同一时刻同时发生 并发: 在同一时间内,多个事情交替执行 并发编程: 比如抢票,秒杀等在同一场景下,有大量的请求访问同一资源, 会出现一些安全性的问题,所以要通过编程来控制多个线程依次访问资源,称…

java并发编程(荣耀典藏版)

大家好 我是月夜枫,聊一聊java中的并发编程,面试工作中也许都会用到,参考了很大博主的博客,整理了很久的文章,虽然还没有全部整理完,后续慢慢更新吧。 并发编程 一、线程的基础概念 一、基础概念 1.1 进…

Java并发编程基础(一篇入门)

1 并发编程简介 1.1 什么是并发编程 所谓并发编程是指在一台处理器上 “同时” 处理多个任务。并发是在同一实体上的多个事件。多个事件在同一时间间隔发生。 并发编程,从程序设计的角度来说,是希望通过某些机制让计算机可以在一个时间段内&#xff0…

关于Java并发编程的总结和思考

编写优质的并发代码是一件难度极高的事情。Java语言从第一版本开始内置了对多线程的支持,这一点在当年是非常了不起的,但是当我们对并发编程有了更深刻的认识和更多的实践后,实现并发编程就有了更多的方案和更好的选择。本文是对并发编程的一…

Java 并发编程

目录 回顾线程 并发编程 并发编程 Java 内存模型(JMM) 编程核心问题--可见性,原子性,有序性 可见性 有序性 原子性 valatile 关键字 CAS(Compare-And-Swap,比较并交换) 原子类 java中的锁 乐观锁/悲观锁 可重用锁(…

JAVA并发编程

并发编程 1.进程与线程 进程 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存。在 指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的。当一个…