Java深入理解并发、线程、与等待通知机制(一)

并发编程概述

  • 并发编程的重要性

    • 大厂招聘要求掌握多线程编程能力。
    • 并发编程是升职加薪的重要技能之一。
    • 并发提升响应速度、实现异步化、充分利用CPU资源。
  • 单核与多核处理

    • 即使在单核处理器上,也可通过并发实现多个任务交替执行。
    • 多核处理器下,并发能真正实现并行执行。
  • QQ/微信并发示例

    • 输入文字、发送消息、接收信息三者同时发生,体现并发特性。
    • 若使用单线程,则需串行完成以上操作,用户体验差。

进程与线程概念解析

  • 进程定义

    • 进程是一个程序的实例,包含指令、内存管理、I/O操作等。
    • 类比面向对象中类与对象的关系,程序是类,进程是对象。
    • 进程是操作系统中资源分配的最小单位。
  • 线程定义

    • 线程是操作系统中CPU调度的最小单位。
    • 一个进程中可以包含多个线程,但线程必须依附于进程存在。
    • Linux早期无独立线程概念,后称为轻量级进程(LWP)。
  • Java中的线程机制

    • JVM本身作为一个进程,内部自动启动多个线程,如主线程、Finalizer线程、Reference Handler线程等。
    • 即使是最简单的Java程序,也会默认启动多个线程。

进程间通信方式

  • 常见IPC机制
    • 管道(Pipe):分为匿名管道(父子进程通信)与命名管道(任意两个进程通信)。
    • 信号(Signal):用于向应用程序发送特定事件通知。
    • 消息队列(Message Queue):类似MQ,用于进程间传递消息。
    • 共享内存(Shared Memory):多个进程访问同一块内存区域,效率高但需同步控制。
    • 信号量(Semaphore):用于控制对共享资源的访问。
    • 套接字(Socket):支持跨机器通信,也可用于本地进程通信(Unix Domain Socket)。

CPU核心与线程关系

  • 物理核心与逻辑处理器

    • 物理核心数决定实际并行能力。
    • 逻辑处理器来自超线程技术,允许一个物理核心模拟多个逻辑核心。
  • Runtime类获取核心数

    • Runtime.getRuntime().availableProcessors() 返回的是逻辑处理器数量。
    • 不同架构平台(Intel vs AMD/ARM)返回结果可能不同。

上下文切换原理

  • 上下文切换定义

    • 操作系统保存当前线程状态并加载另一个线程状态的过程。
    • 包括寄存器、程序计数器、缓存数据等。
  • 上下文切换代价

    • 一次上下文切换通常需要约5,000~20,000个时钟周期。
    • 相较之下,普通指令执行只需几个到几十个时钟周期。
  • 性能调优建议

    • 上下文切换频繁会导致性能下降。
    • 使用工具如vmstatpidstat监控切换频率。

并发与并行区别

  • 并行(Parallelism)

    • 同一时刻执行多个任务。
    • 依赖多核CPU,如两个队伍同时使用两台售货机。
  • 并发(Concurrency)

    • 一段时间内交替执行多个任务。
    • 如一个售货机被两个队伍轮流使用。
    • 体现为时间片轮转下的"看似同时"。

Java线程创建方式

  • 继承Thread类

    • 创建子类并重写run()方法。
    • 实例化后调用start()启动线程。
  • 实现Runnable接口

    • 实现run()方法,传入Thread构造器。
    • 更推荐使用,避免类继承限制。
  • Callable + FutureTask

    • Callable<V>提供返回值,适用于需要结果的任务。
    • FutureTask包装Callable,作为Runnable传入线程。
    • 通过future.get()获取异步执行结果。

线程终止方式

  • 自然终止

    • run()方法执行完毕。
    • 抛出未捕获异常导致提前结束。
  • 强制终止(不推荐)

    • stop()suspend()resume()等方法已废弃。
    • 原因:不会释放资源,易造成死锁、文件损坏等问题。
  • 中断机制(推荐)

    • 调用interrupt()设置中断标志位为true
    • 线程主动检查isInterrupted()interrupted()状态。
    • 阻塞方法(如sleep()get())抛出InterruptedException,可响应中断。

线程启动与运行区别

  • start()方法

    • 启动新线程,在JVM中注册并与操作系统线程绑定。
    • 只能调用一次,否则抛出IllegalThreadStateException
  • run()方法

    • 普通方法,直接调用仅在当前线程中执行。
    • 可重复调用,不影响线程状态。
    • 示例:调用thread.run()将在主线程中执行
相关推荐
xierui12312332 分钟前
AI Agent 隐私架构:本地化重点为什么是登录态与执行权限
java·人工智能·网络安全·架构
cfm_291442 分钟前
Spring AI Tool 调用架构全解
java·人工智能·spring
sun༒1 小时前
Spring @Scheduled 定时任务详解:Cron表达式、执行顺序、优先级与并行调度
java·后端·spring
一次旅行1 小时前
DeepSeek‑V4‑Flash‑Vision‑Exp 小白入门实战|3种传图方式、完整可跑代码、避坑排障
java·前端·人工智能
野生技术架构师1 小时前
Spring Boot 实现数据脱敏:自定义注解 + Jackson 序列化器
java·spring boot·后端
AI人工智能+电脑小能手1 小时前
大白话说Java设计模式-28-模板方法模式(业务实战篇)
java·设计模式·模板方法模式·spring源码·订单系统·代码复用
奥莱维2 小时前
KNX酒店方案_KNX专用线与高端酒店技术逻辑
java·服务器·前端·数据库
工业一体机老司机2 小时前
Linux工业一体机自启动服务配置:systemd服务单元编写与开机优化实战
java·linux·服务器
weixin_538601972 小时前
智能体测开Day56
java
杨丰玮4182 小时前
从零手写Java飞机躲障碍游戏|Swing绘图、鼠标跟随、计时器碰撞检测实战(五)
java·python·游戏·游戏引擎·图形渲染·动画·贴图