当前位置:首页 > 工具 > 正文内容

Java 多线程编程详解

访客 工具 2026年6月18日 1

一、多线程基础概念

1、进程与线程

  • 进程:操作系统资源分配的基本单位,每个进程中可包含多个线程。
  • 线程:CPU 调度的基本单位,代表程序的一条执行路径。

2、并发与并行

  • 并发:在单核 CPU 上通过任务切换实现多个任务交替执行。
  • 并行:在多核 CPU 上真正同时执行多个任务。

3、线程生命周期

Java 中线程包括以下六种状态:

  • New(新建)
  • Runnable(可运行)
  • Blocked(阻塞)
  • Waiting(等待)
  • Timed Waiting(超时等待)
  • Terminated(终止)

4、死锁现象

死锁是指多个线程互相等待对方持有的资源,造成所有线程均无法继续执行的情况。

4.1 死锁形成条件

  • 互斥条件:资源不能被多个线程同时使用。
  • 请求和保持条件:线程已获得部分资源,并继续请求其他资源。
  • 不可剥夺条件:线程已获得的资源不能被强制释放。
  • 循环等待条件:存在线程间的资源循环等待链。

4.2 预防死锁策略

  • 破坏请求和保持条件:一次性申请所有所需资源。
  • 破坏不可剥夺条件:主动释放已占资源。
  • 破坏循环等待条件:统一资源编号,按序申请。

二、多线程实现方式

1、创建线程的方法

1.1 继承 Thread 类

class WorkerThread extends Thread {
    @Override
    public void run() {
        System.out.println("通过继承Thread类执行任务");
    }
    
    public static void main(String[] args) throws InterruptedException {
        WorkerThread worker = new WorkerThread();
        worker.start();
        worker.join();
    }
}

1.2 实现 Runnable 接口

class TaskRunner implements Runnable {
    private final Object prevLock;
    private final Object currLock;
    private final String outputChar;
    
    public TaskRunner(String ch, Object prev, Object curr) {
        this.outputChar = ch;
        this.prevLock = prev;
        this.currLock = curr;
    }
    
    @Override
    public void run() {
        int counter = 10;
        while (counter > 0) {
            synchronized (prevLock) {
                synchronized (currLock) {
                    System.out.print(outputChar);
                    counter--;
                    currLock.notifyAll();
                }
                try {
                    if (counter > 0) {
                        prevLock.wait();
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        Object lockA = new Object();
        Object lockB = new Object();
        Object lockC = new Object();
        
        Thread th1 = new Thread(new TaskRunner("A", lockC, lockA));
        Thread th2 = new Thread(new TaskRunner("B", lockA, lockB));
        Thread th3 = new Thread(new TaskRunner("C", lockB, lockC));
        
        th1.start();
        Thread.sleep(50);
        th2.start();
        Thread.sleep(50);
        th3.start();
        
        th1.join();
        th2.join();
        th3.join();
    }
}

1.3 实现 Callable 接口

import java.util.concurrent.*;
class AsyncTask implements Callable<String> {
    @Override
    public String call() {
        return "异步任务执行完成";
    }
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        AsyncTask task = new AsyncTask();
        FutureTask<String> future = new FutureTask<>(task);
        new Thread(future).start();
        System.out.println(future.get());
    }
}

2、线程控制机制

2.1 等待与唤醒机制

  • wait():使当前线程进入等待状态。
  • notify():随机唤醒一个等待线程。
  • notifyAll():唤醒所有等待线程。

2.2 条件等待机制

  • await():类似 wait(),用于 Lock 框架。
  • signal():类似 notify(),用于 Lock 框架。
  • signalAll():类似 notifyAll(),用于 Lock 框架。

2.3 线程让步

  • yield():暂停当前线程,让出 CPU 时间片。

3、线程常用 API

常见线程方法包括 sleep()、interrupt()、isAlive()、getState() 等。

三、线程池技术

1、线程池优势

  • 减少线程创建销毁开销
  • 提升响应速度
  • 便于统一管理和监控

2、线程池创建

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                     // 核心线程数
    10,                    // 最大线程数
    60L,                   // 空闲线程存活时间
    TimeUnit.SECONDS,      // 时间单位
    new LinkedBlockingQueue<>(), // 工作队列
    Executors.defaultThreadFactory(), // 线程工厂
    new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);

3、预定义线程池

3.1 固定大小线程池

ExecutorService fixedPool = Executors.newFixedThreadPool(4);

3.2 单线程池

ExecutorService singlePool = Executors.newSingleThreadExecutor();

3.3 缓存线程池

ExecutorService cachedPool = Executors.newCachedThreadPool();

3.4 定时任务线程池

ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);
scheduledPool.schedule(() -> System.out.println("延时任务"), 3, TimeUnit.SECONDS);

4、拒绝策略

  • AbortPolicy:抛出异常拒绝新任务
  • DiscardPolicy:静默丢弃新任务
  • DiscardOldestPolicy:丢弃队列头部任务
  • CallerRunsPolicy:由调用线程执行任务

四、线程安全保障

1、线程三大特性

  • 原子性:操作不可分割
  • 可见性:变量修改对其他线程立即可见
  • 有序性:指令执行顺序不被重排序

2、同步机制

2.1 CAS 机制

CAS(Compare And Swap)是一种无锁算法,通过比较并交换实现原子操作。

2.2 Synchronized 关键字

public synchronized void method() {
    // 同步方法
}

public void block() {
    synchronized(this) {
        // 同步代码块
    }
}

2.3 ReentrantLock 锁

import java.util.concurrent.locks.ReentrantLock;
class Counter {
    private int value = 0;
    private final ReentrantLock lock = new ReentrantLock();
    
    public void increment() {
        lock.lock();
        try {
            value++;
        } finally {
            lock.unlock();
        }
    }
}

2.4 Volatile 关键字

Volatile 保证变量的可见性和禁止指令重排序,但不保证原子性。

3、线程局部变量

class LocalStorage {
    private static ThreadLocal<String> storage = new ThreadLocal<>();
    
    public static void main(String[] args) {
        storage.set("主线程数据");
        
        new Thread(() -> {
            storage.set("子线程数据");
            System.out.println(storage.get());
        }).start();
        
        System.out.println(storage.get());
    }
}

相关文章

Trojan服务器搭建与配置

一、整体架构(先对齐认知)Clash Meta (PC / iOS / Android)        ↓ TLS   Trojan Server (443)        ↓     InternetTrojan 的核心是: TLS + HTTPS 流量伪装 看起来像正常网站 非常适合...

Tailscale 的详细用法

Tailscale 是一种基于 WireGuard 协议 的 零配置 VPN(虚拟私有网络)服务,让设备之间能够 安全、加密地直接连接,就像它们在同一个本地网络一样。它的核心特点是 简单、安全、跨平台。Tailscale 非常适合 没有公网 IP、两台电脑不在同一局域网 的场景。 简单来说,Tailscale 是什么?Tailscale 是一款让你的各种设备(电脑、服务器、手机...

Clash Tun 模式 导致 爱快(iKuai SD-Wan)内网域名无法访问

一、Clash  DNS 配置dns:  enable: true  listen: 0.0.0.0:53  ipv6: true  enhanced-mode: redir-host  nameserver:    - 223.5.5.5    - 223.6.6.6iKuai 内网域名 ...

深入解析Node.js运行环境与异步I/O架构

深入解析Node.js运行环境与异步I/O架构

核心定义与价值Node.js本质上是一个JavaScript运行环境,而非编程语言或应用框架。它赋予了JavaScript脱离浏览器在服务端、命令行工具及网络应用中执行的能力。其核心意义在于:用单一语言打通前后端开发壁垒。基于事件驱动与非阻塞I/O的架构特性,Node.js在处理API网关、实时通信及微服务等I/O密集型场景时表现卓越,已成为现代后端工程的主流选择。浏览器沙箱限制1995年Java...

ADO.NET SQL参数化查询的最佳实践

在 ADO.NET 中执行 SQL 查询时,参数化查询是一种关键的安全措施和性能优化手段。它通过将 SQL 命令和用户提供的数据分开处理,有效防止了 SQL 注入攻击,并有助于数据库缓存执行计划。下面总结了几种常用的参数化查询方式。 1. 使用 SqlParameter 对象(推荐) 这是最推荐的参数化查询方式。通过显式创建 SqlParameter 对象,您可以精确控制参数的类...

基于ELK的日志集中化分析系统搭建

构建统一日志管理平台的必要性 在分布式架构中,各服务节点独立运行,日志分散存储于不同主机。传统通过命令行工具如grep、awk逐个检索日志的方式,在数据量庞大时效率极低,难以实现快速定位问题。为提升运维效率,需建立集中式日志处理体系,具备日志采集、传输、存储、分析与告警能力。 ELK技术栈核心组件解析 Elasticsearch:分布式搜索引擎,支持全文检索、实时数据分析和高可用集群部署,...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。