Java-多线程

一、 为什么要学多线程?这3个理由够不够!

在这个追求高性能的时代,单线程程序早已满足不了业务需求。试想一下:你的接口需要处理上万级并发请求,单线程串行执行直接卡死;你的数据批量处理任务跑了半天没结果,资源利用率低到离谱。

而Java多线程,就是解决这些问题的"金钥匙":

  1. 提升程序执行效率:将耗时任务异步化,CPU和IO资源并行工作,效率直接翻倍。

  2. 应对高并发场景:电商秒杀、直播弹幕、金融交易,没有多线程寸步难行。

  3. 大厂面试必考点:不管是校招还是社招,多线程+并发编程都是面试官的"宠儿",掌握它=拿到高薪入场券。

二、 零基础入门:Java多线程的3种创建方式

很多新手一上来就被线程的创建劝退,其实核心就3种方式,简单到离谱:

  1. 继承Thread类:重写run()方法,直接new对象调用start()启动,适合简单场景。

  2. 实现Runnable接口:解耦任务和线程,避免单继承限制,是实际开发中更推荐的方式。

  3. 实现Callable接口:支持返回值和异常抛出,搭配FutureTask获取异步执行结果,解决前两种方式"拿不到返回值"的痛点。

代码示例(Callable+FutureTask):

import java.util.concurrent.Callable;

import java.util.concurrent.FutureTask;

public class CallableDemo implements Callable<Integer> {

@Override

public Integer call() throws Exception {

int sum = 0;

for (int i = 1; i <= 100; i++) {

sum += i;

}

return sum;

}

public static void main(String[] args) {

FutureTask<Integer> futureTask = new FutureTask<>(new CallableDemo());

new Thread(futureTask).start();

try {

// 获取异步执行结果

System.out.println("1-100求和结果:" + futureTask.get());

} catch (Exception e) {

e.printStackTrace();

}

}

}

三、 进阶必学:线程安全的核心------锁机制

线程安全是多线程开发的"拦路虎",而锁就是解决它的关键。这里只讲最核心、最常用的两种锁:

  1. synchronized关键字:Java内置的隐式锁,可修饰方法或代码块,自动加锁和释放锁,适合简单的同步场景。它的底层是通过对象监视器(Monitor) 实现的,新手也能快速上手。

  2. Lock接口:显式锁,代表实现是ReentrantLock,支持公平锁/非公平锁、可中断锁、尝试获取锁,灵活性远超synchronized。记住:使用Lock必须手动释放锁,建议放在finally块中!

核心区别对比:

特性 synchronized ReentrantLock

锁的释放 自动释放 手动释放(finally)

锁的类型 非公平锁 公平/非公平锁可选

响应中断 不支持 支持

尝试获取锁 不支持 支持(tryLock())

四、 性能优化神器:线程池,告别手动创建线程!

手动创建线程的弊端太多了:线程创建和销毁消耗资源、无限制创建线程导致OOM、线程缺乏统一管理。而线程池就是为解决这些问题而生的!

Java提供了Executors工具类快速创建线程池,但实际开发中更推荐使用ThreadPoolExecutor手动创建,避免默认参数带来的坑。

ThreadPoolExecutor核心参数:

• corePoolSize:核心线程数,线程池常驻的线程数量

• maximumPoolSize:最大线程数,线程池能容纳的最大线程数量

• keepAliveTime:非核心线程的空闲存活时间

• workQueue:任务队列,存放等待执行的任务

• threadFactory:线程工厂,用于创建线程

• handler:拒绝策略,任务过多时的处理方式

核心拒绝策略:

• AbortPolicy:直接抛出异常(默认)

• CallerRunsPolicy:由调用者线程执行任务

• DiscardPolicy:直接丢弃任务

• DiscardOldestPolicy:丢弃队列中最老的任务

五、 避坑指南:多线程开发的5个常见误区

  1. 调用run()方法启动线程:错!run()方法只是普通方法调用,必须用start()才会真正启动新线程。

  2. 认为volatile能保证原子性:大错特错!volatile只能保证可见性和有序性,不能保证原子性,原子性需要synchronized或CAS来保证。

  3. 线程池参数设置不合理:核心线程数过大导致资源浪费,过小导致任务堆积;任务队列选不对直接影响性能。

  4. 忽略线程安全问题:在多线程环境下共享可变变量,不做同步处理,必然导致数据错乱。

  5. 滥用线程池:不管什么任务都用线程池,反而增加了线程调度的开销,简单任务直接串行执行更高效。

六、 实战总结:学好Java多线程的3个关键

  1. 理解底层原理:搞懂JVM的内存模型、线程的生命周期、锁的实现机制,而不是死记硬背API。

  2. 多写代码实战:从简单的卖票案例,到复杂的线程池异步任务,只有动手才能发现问题、解决问题。

  3. 多看源码:研究ThreadPoolExecutor、ReentrantLock的源码,看看大厂工程师是怎么写高并发代码的。

相关推荐
abcnull1 小时前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡1 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
我的xiaodoujiao2 小时前
API 接口自动化测试详细图文教程学习系列16--项目实战演练3
python·学习·测试工具·pytest
juniperhan2 小时前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054732 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路2 小时前
C++23概述
java·c++·c++23
复利人生 复利日知录 赋能循环2 小时前
2026年复利精进:我的每日觉醒与成长密码
学习·思维模型·知识复利·复利·独立
专注API从业者3 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
sakiko_3 小时前
UIKit学习笔记4-使用UITableView制作滚动视图
笔记·学习·ios·swift·uikit