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

Java 多线程编程:从基础到实战!

全文目录:

    • 开篇语
    • **前言**
    • 1. **线程基础概念**
      • 1.1 **什么是线程?**
      • 1.2 **线程的生命周期**
    • 2. **线程的创建与启动**
      • 2.1 **继承 `Thread` 类**
      • 2.2 **实现 `Runnable` 接口**
    • 3. **线程的同步**
      • 3.1 **使用 `synchronized` 关键字**
        • 示例:使用 `synchronized` 修饰方法
      • 3.2 **使用 `ReentrantLock`**
    • 4. **线程的通信**
      • 4.1 **使用 `wait()` 和 `notify()`**
    • 5. **线程池**
      • 5.1 **使用 `ExecutorService` 创建线程池**
    • 6. **总结**
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  多线程编程是 Java 中的一个核心概念,它允许多个线程同时执行任务,从而提高程序的效率和响应性。在现代应用程序中,多线程编程无处不在,尤其是在处理高并发任务时。今天,我们将从基础到实战深入讲解 Java 的多线程编程,帮助你更好地理解和应用它。

1. 线程基础概念

1.1 什么是线程?

  线程是操作系统能够进行调度的最小单位。每个 Java 程序在启动时,都会自动创建一个主线程。通过多线程编程,多个线程可以同时执行不同的任务。

  线程是属于进程的,每个线程都有自己的执行路径。多线程可以并发地执行任务,提高程序的效率,尤其是在 CPU 密集型和 I/O 密集型任务中。

1.2 线程的生命周期

  线程的生命周期主要包括以下几个阶段:

  • 新建(New):线程对象创建后,还未调用 start() 方法时,处于新建状态。
  • 就绪(Runnable):线程调用 start() 方法后,处于就绪状态。操作系统会将就绪的线程分配 CPU 时间片,开始执行任务。
  • 运行(Running):线程获得 CPU 时间片后,进入运行状态,开始执行任务。
  • 阻塞(Blocked):线程在等待某些资源(如 I/O、锁等)时,会进入阻塞状态。
  • 死亡(Dead):线程执行完任务后进入死亡状态。

2. 线程的创建与启动

在 Java 中,创建和启动线程的方式有两种:继承 Thread 类和实现 Runnable 接口。

2.1 继承 Thread

  通过继承 Thread 类并重写 run() 方法来实现线程。然后通过调用 start() 方法来启动线程。

class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程 " + Thread.currentThread().getName() + " 正在执行");}public static void main(String[] args) {MyThread thread1 = new MyThread();MyThread thread2 = new MyThread();thread1.start();  // 启动线程thread2.start();}
}

2.2 实现 Runnable 接口

  通过实现 Runnable 接口,并将 Runnable 实现类传递给 Thread 构造函数,再调用 start() 方法来启动线程。这个方法的优势是支持多继承。

class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("线程 " + Thread.currentThread().getName() + " 正在执行");}public static void main(String[] args) {MyRunnable task = new MyRunnable();Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();  // 启动线程thread2.start();}
}

3. 线程的同步

多线程编程中,一个常见的问题是多个线程访问共享资源时,可能会导致数据不一致的问题。为了解决这个问题,Java 提供了多种同步机制。

3.1 使用 synchronized 关键字

synchronized 是 Java 中用于控制对共享资源的访问的关键字。它可以确保同一时刻只有一个线程能够执行被 synchronized 修饰的代码块。

示例:使用 synchronized 修饰方法
class Counter {private int count = 0;public synchronized void increment() {count++;}public synchronized int getCount() {return count;}
}public class SynchronizedExample {public static void main(String[] args) {Counter counter = new Counter();// 创建多个线程并执行任务Thread thread1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终计数值:" + counter.getCount());}
}

3.2 使用 ReentrantLock

ReentrantLock 是一种更灵活的锁机制,它比 synchronized 更加可控,支持尝试锁、定时锁等高级功能。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class Counter {private int count = 0;private Lock lock = new ReentrantLock();public void increment() {lock.lock();  // 获取锁try {count++;} finally {lock.unlock();  // 释放锁}}public int getCount() {return count;}
}public class LockExample {public static void main(String[] args) {Counter counter = new Counter();// 创建多个线程并执行任务Thread thread1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终计数值:" + counter.getCount());}
}

4. 线程的通信

在某些情况下,多个线程需要相互协作,完成任务。Java 提供了 wait()notify()notifyAll() 方法来进行线程间的通信。

4.1 使用 wait()notify()

wait() 方法使当前线程进入等待状态,直到其他线程调用 notify()notifyAll() 方法时,当前线程才会被唤醒。

class SharedResource {private boolean flag = false;public synchronized void produce() throws InterruptedException {while (flag) {wait();  // 如果已经生产了,就等待}System.out.println("生产者生产了一个产品");flag = true;notify();  // 唤醒消费者}public synchronized void consume() throws InterruptedException {while (!flag) {wait();  // 如果没有产品,就等待}System.out.println("消费者消费了一个产品");flag = false;notify();  // 唤醒生产者}
}public class WaitNotifyExample {public static void main(String[] args) {SharedResource resource = new SharedResource();// 生产者线程Thread producer = new Thread(() -> {try {while (true) {resource.produce();Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}});// 消费者线程Thread consumer = new Thread(() -> {try {while (true) {resource.consume();Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}});producer.start();consumer.start();}
}

5. 线程池

  线程池是为了减少线程创建和销毁的开销,提升程序效率而设计的。Java 提供了 ExecutorService 接口和它的实现类 ThreadPoolExecutor 来管理线程池。

5.1 使用 ExecutorService 创建线程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ExecutorServiceExample {public static void main(String[] args) {// 创建一个固定大小的线程池ExecutorService executor = Executors.newFixedThreadPool(3);// 提交任务给线程池for (int i = 0; i < 5; i++) {executor.submit(() -> {System.out.println("线程 " + Thread.currentThread().getName() + " 正在执行");});}// 关闭线程池executor.shutdown();}
}

6. 总结

  多线程编程是 Java 编程中的一个重要部分,它能够提升程序的性能和响应速度。通过学习 Java 中的线程创建、同步、通信和线程池等内容,你可以更好地理解如何在 Java 中实现并发处理。

  今天,我们从 Java 线程的基础概念到高级特性进行了详细的讲解,并通过实例帮助大家更好地理解多线程编程的核心要点。希望这篇文章能够帮助你更好地掌握 Java 多线程编程!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

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

相关文章:

  • Ceph集群OSD运维手册:基础操作与节点扩缩容实战
  • MSTP 实验拓扑配置(ENSP)
  • 自动化创业机器人:现状、挑战与Y Combinator的启示
  • hadoop中的序列化和反序列化(3)
  • React学习路线-Deepseek版
  • 搭建spark伪分布集群
  • windows10 环境下通过huggingface_hub下载huggingface社区模型
  • 子集树算法文档
  • 驱动开发硬核特训 · 专题篇:Vivante GPU 与 DRM 图形显示体系全解析(i.MX8MP 平台实战)
  • 机器学习在信用卡欺诈检测中的应用思考
  • 4.9/Q1,GBD数据库最新文章解读
  • Admyral - 可扩展的GRC工程自动化平台
  • 【MCP】function call与mcp若干问题整理
  • 汽车加气站操作工考试知识点总结
  • 云渲染农场:让复杂渲染变得简单高效
  • OpenCV计算机视觉实战(3)——计算机图像处理基础
  • OpenCV 中用于背景分割的一个类cv::bgsegm::BackgroundSubtractorGMG
  • DeepSeek智能时空数据分析(八):NL2SQL绘制河流-轨迹缓冲区如何生成
  • 如何在自己的服务器上部署静态网页并通过IP地址进行访问
  • 使用 Celery + Redis + Eventlet 实现 Python 异步编程(Windows 环境)
  • STM32--TIM--函数
  • 卢dns免费二级域名分发
  • 【Python os模块完全指南】从基础到高效文件操作
  • 智算中心基础设施0-1建设全流程及投产后的运维
  • 物业设备管理的“多系统协同”模式:ERP、IoT与工单系统如何联动?
  • 202505扫描主机:升级Tomcat解决Tomcat 安全漏洞(CVE-2025-24813)【为了同一个tomcat版本安装多个服务】
  • 什么是Blender?怎么获取下载Blender格式文件模型
  • Pinecone向量库 VS Redis
  • DeepSeek的100个应用场景
  • 什么是TCC?什么是二阶段提交?三阶段提交?