当前位置: 首页 > news >正文

Java多线程编程详解

Java多线程编程详解

前言

多线程编程是Java开发中非常重要的内容,能够充分利用多核CPU资源,提高程序的并发能力和响应速度。本文将系统介绍Java多线程的基础知识、常用技术、并发工具类、线程池、常见问题及调优建议,帮助开发者掌握多线程编程的核心要点。

1. 基础概念

1.1 进程与线程

  • 进程:操作系统资源分配的最小单位,每个进程拥有独立的内存空间。
  • 线程:CPU调度和执行的最小单位,同一进程下的多个线程共享内存资源。

1.2 并发与并行

  • 并发(Concurrency):同一时间段内多个任务交替执行。
  • 并行(Parallelism):同一时刻多个任务同时执行(多核CPU)。

2. 线程的创建方式

2.1 继承Thread类

public class MyThread extends Thread {@Overridepublic void run() {System.out.println("继承Thread方式创建线程:" + Thread.currentThread().getName());}public static void main(String[] args) {MyThread t1 = new MyThread();t1.start();}
}

2.2 实现Runnable接口

public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("实现Runnable方式创建线程:" + Thread.currentThread().getName());}public static void main(String[] args) {Thread t1 = new Thread(new MyRunnable());t1.start();}
}

2.3 实现Callable接口 + FutureTask

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {System.out.println("实现Callable方式创建线程:" + Thread.currentThread().getName());return 100;}public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable());Thread t1 = new Thread(futureTask);t1.start();System.out.println("返回结果:" + futureTask.get());}
}

2.4 线程池方式

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolDemo {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(2);executor.execute(() -> System.out.println("线程池方式创建线程:" + Thread.currentThread().getName()));executor.shutdown();}
}

3. 线程的生命周期

  • 新建(New)
  • 就绪(Runnable)
  • 运行(Running)
  • 阻塞(Blocked/Waiting/Timed Waiting)
  • 死亡(Terminated)

4. 线程同步与互斥

4.1 synchronized关键字

  • 修饰实例方法、静态方法、代码块
  • 保证同一时刻只有一个线程执行同步代码
public class SynchronizedDemo {private int count = 0;public synchronized void increment() {count++;}public void syncBlock() {synchronized (this) {count++;}}
}

4.2 Lock接口

  • 更灵活的同步控制
  • 支持公平锁、可重入、可中断
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockDemo {private int count = 0;private final Lock lock = new ReentrantLock();public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}
}

4.3 volatile关键字

  • 保证变量的可见性,不保证原子性
  • 适用于状态标记、单例模式等场景
public class VolatileDemo {private volatile boolean running = true;public void stop() {running = false;}
}

4.4 原子类(Atomic)

  • 提供原子操作,避免加锁开销
import java.util.concurrent.atomic.AtomicInteger;public class AtomicDemo {private AtomicInteger count = new AtomicInteger(0);public void increment() {count.incrementAndGet();}
}

5. 常用并发工具类

5.1 CountDownLatch

  • 计数器,等待一组线程完成后再继续执行
import java.util.concurrent.CountDownLatch;public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(3);for (int i = 0; i < 3; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 完成任务");latch.countDown();}).start();}latch.await();System.out.println("所有子线程执行完毕");}
}

5.2 CyclicBarrier

  • 回环栅栏,允许一组线程互相等待,直到到达某个公共屏障点
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("所有线程到达屏障,开始执行后续任务"));for (int i = 0; i < 3; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 到达屏障");try {barrier.await();} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}).start();}}
}

5.3 Semaphore

  • 信号量,控制同时访问某个资源的线程数量
import java.util.concurrent.Semaphore;public class SemaphoreDemo {public static void main(String[] args) {Semaphore semaphore = new Semaphore(2);for (int i = 0; i < 5; i++) {new Thread(() -> {try {semaphore.acquire();System.out.println(Thread.currentThread().getName() + " 获得许可");Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}).start();}}
}

5.4 Exchanger

  • 线程间数据交换工具
import java.util.concurrent.Exchanger;public class ExchangerDemo {public static void main(String[] args) {Exchanger<String> exchanger = new Exchanger<>();new Thread(() -> {try {String data = "A线程数据";String result = exchanger.exchange(data);System.out.println("A线程收到: " + result);} catch (InterruptedException e) {e.printStackTrace();}}).start();new Thread(() -> {try {String data = "B线程数据";String result = exchanger.exchange(data);System.out.println("B线程收到: " + result);} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}

6. 线程池

6.1 线程池的优势

  • 线程复用,减少频繁创建和销毁线程的开销
  • 统一管理线程资源,便于监控和调优
  • 控制最大并发数,防止资源耗尽

6.2 线程池的核心参数

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • keepAliveTime:空闲线程存活时间
  • workQueue:任务队列
  • threadFactory:线程工厂
  • handler:拒绝策略

6.3 线程池的创建方式

import java.util.concurrent.*;public class ThreadPoolConfigDemo {public static void main(String[] args) {ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS,new LinkedBlockingQueue<>(100),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());executor.execute(() -> System.out.println("自定义线程池执行任务"));executor.shutdown();}
}

6.4 常用线程池类型

  • newFixedThreadPool:固定线程数线程池
  • newCachedThreadPool:可缓存线程池
  • newSingleThreadExecutor:单线程池
  • newScheduledThreadPool:定时任务线程池

7. 常见问题与调优建议

7.1 死锁

  • 多个线程互相等待对方释放资源,导致程序无法继续执行
  • 解决方法:避免嵌套锁、资源有序分配、使用tryLock

7.2 活锁

  • 线程不断地让步和重试,始终无法推进进程
  • 解决方法:增加随机等待、限制重试次数

7.3 线程安全问题

  • 竞态条件、可见性、原子性问题
  • 解决方法:合理使用同步机制、原子类、并发容器

7.4 线程池参数调优

  • 根据业务特点合理设置核心线程数、队列长度、拒绝策略
  • 监控线程池状态,及时扩容或降级

7.5 其他建议

  • 避免在多线程环境下使用非线程安全的类(如SimpleDateFormat
  • 合理拆分任务,避免单个任务执行时间过长
  • 使用高并发包(java.util.concurrent)替代手动加锁

8. 总结

Java多线程编程是提升系统性能和并发能力的关键技术。掌握线程的创建、同步、并发工具类和线程池的使用,能够有效应对高并发场景下的各种挑战。实际开发中要注意线程安全、资源管理和性能调优,结合具体业务场景选择合适的并发方案。


本文系统介绍了Java多线程编程的核心知识点,适合初学者入门和有经验开发者查阅参考。

http://www.xdnf.cn/news/781813.html

相关文章:

  • 40、响应处理-【源码分析】-基于请求参数的内容协商原理
  • 一周学会Pandas2之Python数据处理与分析-Pandas2数据绘图与可视化
  • Kafka 的优势是什么?
  • 网络安全:钓鱼邮件、虚假网站与诈骗信息的预防与应对
  • seafile:ubuntu搭建社区版seafile12.0
  • 机器学习——随机森林算法
  • 【R语言编程绘图-mlbench】
  • 【Mysql】隐式转换造成索引失效
  • MaxCompute开发UDF和UDTF案例
  • 运行shell脚本时报错/bin/bash^M: 解释器错误: 没有那个文件或目录
  • python,shell,linux,bash概念的不同和对比联系
  • 【动手学机器学习】第三章模式识别与机器学习经典算法——k 近邻算法
  • Modbus转Ethernet IP赋能挤出吹塑机智能监控
  • 06-排序
  • cf1600-1900每天刷2-3道打卡(2)
  • leetcode47.全排列II:HashSet层去重与used数组枝去重的双重保障
  • 大疆无人机的二次开发
  • 数据库的操作
  • Leetcode-7 寻找用户推荐人
  • AI健康小屋+微高压氧舱:科技如何重构我们的健康防线?
  • 吞咽与营养并重:进行性核上性麻痹的饮食之道
  • 帝国CMS QQ登录插件最新版 获取QQ头像和QQ昵称
  • Nginx + Tomcat 负载均衡、动静分离群集
  • Nginx+Tomcat 负载均衡、动静分离
  • 【学习笔记】深度学习-过拟合解决方案
  • H5动态文字效果开发经验分享
  • 20250603在荣品的PRO-RK3566开发板的Android13下的使用命令行来查看RK3566的温度【显示优化版本】
  • 批量大数据并发处理中的内存安全与高效调度设计(以Qt为例)
  • Android App引用vendor编写的jni动态库
  • ESP32开发之LED闪烁和呼吸的实现