软件开发进阶技能之编程语言深度运用(三)

简介: 教程来源 https://bslm2020.com/ 本节深入解析并发与异步编程核心:厘清并行/并发、线程/协程本质差异;梳理回调→Promise→async/await演进脉络;详解锁、原子操作、RWMutex等同步机制;剖析数据竞争与死锁成因及规避策略,助开发者安全高效驾驭多核时代。

第三部分:并发与异步编程模型 —— 驾驭多核时代的力量

现代计算机多核处理器普及,充分利用并发和并行是提升程序性能的关键。但并发编程也带来了数据竞争、死锁、线程安全等复杂问题。深度掌握语言的并发模型,能够安全高效地编写并发程序。

3.1 并发的基本概念:并行 vs 并发,线程 vs 协程
并发:多个任务在逻辑上同时执行(交替进行)。

并行:多个任务在物理上同时执行(需要多核)。

线程:操作系统调度的最小单位,切换成本较高(几微秒到几十微秒)。

协程:用户态轻量级线程,由语言运行时调度,切换成本极低(纳秒级),可以创建数十万个。

不同语言提供的并发原语:
image.png
3.2 异步编程模型:回调 → Promise → async/await 的演进
异步编程允许程序在等待I/O时执行其他任务,避免线程阻塞。理解异步模型是编写高响应、高吞吐应用的基础。

示例15:JavaScript的Promise链与async/await

// 模拟异步操作
function fetchUser(id) {
    return new Promise(resolve => {
        setTimeout(() => resolve({ id, name: `User${id}` }), 100);
    });
}

function fetchPosts(userId) {
    return new Promise(resolve => {
        setTimeout(() => resolve([`Post1 by ${userId}`, `Post2 by ${userId}`]), 100);
    });
}

// Promise链式调用
fetchUser(1)
    .then(user => {
        console.log(user.name);
        return fetchPosts(user.id);
    })
    .then(posts => {
        console.log(posts);
    })
    .catch(err => console.error(err));

// async/await 更清晰的写法
async function displayUserContent(id) {
    try {
        const user = await fetchUser(id);
        console.log(user.name);
        const posts = await fetchPosts(user.id);
        console.log(posts);
    } catch (err) {
        console.error(err);
    }
}
displayUserContent(2);

深度解释:async函数返回一个Promise,await会暂停当前函数的执行,直到Promise完成,但不会阻塞事件循环。这比回调地狱(Callback Hell)可读性高得多。

示例16:Python的asyncio实现并发网络请求

import asyncio
import aiohttp

async def fetch_url(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    urls = [
        'http://example.com',
        'http://example.org',
        'http://example.net',
    ]
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
        for url, html in zip(urls, results):
            print(f"{url}: {len(html)} bytes")

asyncio.run(main())

关键点:asyncio.gather并发执行多个协程。在等待网络响应时,事件循环可以切换到其他协程,实现高效I/O并发。

3.3 多线程同步:锁、原子操作、并发集合
当多个线程共享可变状态时,必须使用同步机制来保证数据一致性。

示例17:Java中的线程安全计数器比较

// 非线程安全
class UnsafeCounter {
    private int count = 0;
    public void increment() { count++; }  // 多线程下丢失更新
    public int get() { return count; }
}

// 使用synchronized
class SynchronizedCounter {
    private int count = 0;
    public synchronized void increment() { count++; }
    public synchronized int get() { return count; }
}

// 使用AtomicInteger(无锁CAS)
import java.util.concurrent.atomic.AtomicInteger;
class AtomicCounter {
    private AtomicInteger count = new AtomicInteger(0);
    public void increment() { count.incrementAndGet(); }
    public int get() { return count.get(); }
}

// 使用LongAdder(高并发下更好)
import java.util.concurrent.atomic.LongAdder;
class AdderCounter {
    private LongAdder count = new LongAdder();
    public void increment() { count.increment(); }
    public long get() { return count.sum(); }
}

性能对比:synchronized适合低竞争场景;AtomicInteger基于CAS,没有锁的开销,但在高竞争下可能自旋;LongAdder通过分段计数进一步减少竞争。进阶开发者会根据场景选择合适的同步工具。

示例18:Go的Mutex和RWMutex

type SafeCounter struct {
    mu sync.Mutex
    m  map[string]int
}

func (c *SafeCounter) Inc(key string) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.m[key]++
}

func (c *SafeCounter) Value(key string) int {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.m[key]
}

// 读多写少场景使用RWMutex,允许并发读
type SafeMap struct {
    mu sync.RWMutex
    m  map[string]string
}

func (s *SafeMap) Get(key string) string {
    s.mu.RLock()
    defer s.mu.RUnlock()
    return s.m[key]
}

3.4 数据竞争与死锁的检测与避免
数据竞争:多个线程同时访问同一内存位置,至少有一个是写操作,且没有同步。Go语言内置了数据竞争检测器:go test -race。

死锁:两个或多个线程互相等待对方持有的锁,导致永久阻塞。

示例19:Java死锁示例及解决方法

public class DeadlockDemo {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    public void method1() {
        synchronized(lock1) {
            sleep(100);  // 模拟工作
            synchronized(lock2) {
                System.out.println("method1 done");
            }
        }
    }

    public void method2() {
        synchronized(lock2) {
            sleep(100);
            synchronized(lock1) {
                System.out.println("method2 done");
            }
        }
    }

    private void sleep(int ms) { try { Thread.sleep(ms); } catch(Exception e) {} }

    public static void main(String[] args) {
        DeadlockDemo demo = new DeadlockDemo();
        new Thread(demo::method1).start();
        new Thread(demo::method2).start();
    }
}

避免死锁的原则:

固定锁顺序:总是以相同的顺序获取锁。例如,总是先获取lock1再获取lock2。

使用超时尝试:tryLock(timeout)(Java),如果获取失败则释放已持有的锁并重试。

减少锁粒度:使用并发集合(ConcurrentHashMap)或无锁数据结构。

使用更高级的同步工具:如java.util.concurrent的Semaphore、CountDownLatch等。
来源:
https://zlpow.cn/

相关文章
|
15天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
5728 29
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
10天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
1165 2
|
7天前
|
人工智能 安全 定位技术
CodeGraph深度解析 让Claude Code工具调用直降七成的核心原理与实操教程
如今以Claude Code为代表的AI编程智能体已经成为开发者日常编码、项目重构、漏洞修复的必备工具。但在长期使用过程中,几乎所有开发者都会遇到同一个明显痛点:AI虽然具备强大的代码生成与分析能力,却常常陷入盲目探索的循环中。
927 1
|
17天前
|
人工智能 自然语言处理 供应链
|
7天前
|
人工智能 弹性计算 安全
阿里云618活动时间、活动入口、优惠活动详细解读
2026年阿里云618创新加速季已全面开启,作为年度力度最大的云产品促销活动,本次大促覆盖轻量应用服务器、ECS云服务器、GPU云服务器、数据库、AI算力、安全服务、CDN等全品类产品,推出5亿元算力补贴、新用户限时秒杀、普惠满减、企业专享、免费试用、云大使返佣等多重福利,个人开发者、中小企业、AI团队均可享受专属低价。本文将系统梳理2026年阿里云618活动的完整时间节点、官方参与入口、各类优惠细则、使用规则、热门产品推荐及实操代码,帮助用户精准参与、高效省钱,以最低成本完成上云部署。
704 3
|
23天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3826 15
|
8天前
|
运维
欢迎报名|2026 Agentic AICon—智能体基础设施与AgentOps专场,邀您参会
欢迎报名|2026 Agentic AICon—智能体基础设施与AgentOps专场,邀您参会
1421 0