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()将在主线程中执行
相关推荐
夜空下的星2 小时前
springboot实现Minio大文件分片下载
java·spring boot·后端
Huangxy__2 小时前
接口的的的~
java
廋到被风吹走2 小时前
【MySql】超时问题分析
java·数据库·mysql
云创智城-yuncitys2 小时前
[特殊字符]⚡ 停充一体化云平台:基于微服务架构的城市智慧停车+新能源充电解决方案
java·微服务·架构
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 高效便捷的民航订票系统为例,包含答辩的问题和答案
java
零雲2 小时前
java面试:Spring事务失效的场景有哪些?
java·数据库·面试
二月十六2 小时前
运行 ‘XXXX‘ 时出错 运行 XXXX时出错。命令行过长。 通过 JAR 清单或通过类路径文件缩短命令行,然后重新运行。
java·jar
毕设源码-赖学姐3 小时前
【开题答辩全过程】以 鸡场养殖管理系统为例,包含答辩的问题和答案
java
sheji34163 小时前
【开题答辩全过程】以 高校自习室智能化管理系统为例,包含答辩的问题和答案
java