HarmonyOS从入门到精通:线程与并发

引言

在现代应用开发中,合理利用多线程和并发编程是提升应用性能的关键。本文将详细介绍鸿蒙系统中的线程管理和并发编程技术,帮助开发者构建高性能、响应迅速的应用程序。

线程基础知识

1. 线程类型

鸿蒙系统支持多种线程类型:

  • 主线程(UI线程)
  • 工作线程(Worker线程)
  • 后台线程
  • 定时器线程

2. 线程优先级

鸿蒙系统定义了不同的线程优先级:

  • 最高优先级:系统关键任务
  • 高优先级:用户交互相关
  • 普通优先级:一般任务
  • 低优先级:后台任务
  • 最低优先级:空闲任务

线程管理实战

1. Worker线程管理

// worker.ts
import worker from '@ohos.worker';

// Worker线程处理函数
onmessage = function(e) {
    // 执行耗时操作
    const result = performHeavyTask(e.data);
    // 发送结果回主线程
    postMessage(result);
}

function performHeavyTask(data: any): any {
    // 模拟耗时计算
    let result = 0;
    for (let i = 0; i < data.iterations; i++) {
        result += Math.sqrt(i);
    }
    return result;
}

// 监听错误事件
onerror = function(e) {
    console.error('Worker错误:', e);
}
// 主线程代码
export class WorkerManager {
    private worker: worker.Worker | null = null;

    // 创建Worker线程
    public createWorker(): boolean {
        try {
            this.worker = new worker.Worker('worker.js');
            this.setupWorkerListeners();
            return true;
        } catch (error) {
            console.error('创建Worker失败:', error);
            return false;
        }
    }

    // 设置Worker监听器
    private setupWorkerListeners(): void {
        if (!this.worker) return;

        this.worker.onmessage = (e) => {
            console.info('收到Worker结果:', e.data);
        };

        this.worker.onerror = (e) => {
            console.error('Worker错误:', e);
        };
    }

    // 发送任务到Worker
    public sendTask(task: any): void {
        if (!this.worker) {
            console.error('Worker未初始化');
            return;
        }
        this.worker.postMessage(task);
    }

    // 终止Worker
    public terminateWorker(): void {
        if (this.worker) {
            this.worker.terminate();
            this.worker = null;
        }
    }
}

2. 异步任务管理器

export class AsyncTaskManager {
    // 执行异步任务
    public async executeTask<T>(
        task: () => Promise<T>,
        timeout: number = 5000
    ): Promise<T> {
        try {
            return await Promise.race([
                task(),
                this.createTimeout(timeout)
            ]);
        } catch (error) {
            console.error('任务执行失败:', error);
            throw error;
        }
    }

    // 创建超时Promise
    private createTimeout(timeout: number): Promise<never> {
        return new Promise((_, reject) => {
            setTimeout(() => {
                reject(new Error(`任务超时(${timeout}ms)`));
            }, timeout);
        });
    }

    // 批量执行任务
    public async executeBatch<T>(
        tasks: Array<() => Promise<T>>,
        concurrency: number = 3
    ): Promise<T[]> {
        const results: T[] = [];
        const executing: Promise<void>[] = [];

        for (const task of tasks) {
            const p = Promise.resolve().then(async () => {
                const result = await task();
                results.push(result);
            });

            executing.push(p);

            if (executing.length >= concurrency) {
                await Promise.race(executing);
            }
        }

        await Promise.all(executing);
        return results;
    }
}

3. 线程池实现

export class ThreadPool {
    private workers: worker.Worker[] = [];
    private taskQueue: Array<{
        task: any;
        resolve: (value: any) => void;
        reject: (reason: any) => void;
    }> = [];
    private readonly maxWorkers: number;

    constructor(maxWorkers: number = 4) {
        this.maxWorkers = maxWorkers;
    }

    // 初始化线程池
    public initialize(): void {
        for (let i = 0; i < this.maxWorkers; i++) {
            this.createWorker();
        }
    }

    // 创建工作线程
    private createWorker(): void {
        const worker = new worker.Worker('worker.js');
        
        worker.onmessage = (e) => {
            this.handleWorkerMessage(worker, e.data);
        };

        worker.onerror = (e) => {
            this.handleWorkerError(worker, e);
        };

        this.workers.push(worker);
    }

    // 提交任务
    public submitTask(task: any): Promise<any> {
        return new Promise((resolve, reject) => {
            this.taskQueue.push({
                task,
                resolve,
                reject
            });
            this.scheduleTask();
        });
    }

    // 调度任务
    private scheduleTask(): void {
        const availableWorker = this.workers.find(w => !w['busy']);
        if (availableWorker && this.taskQueue.length > 0) {
            const task = this.taskQueue.shift();
            if (task) {
                availableWorker['busy'] = true;
                availableWorker.postMessage(task.task);
                availableWorker['currentTask'] = task;
            }
        }
    }

    // 处理工作线程消息
    private handleWorkerMessage(worker: worker.Worker, result: any): void {
        const task = worker['currentTask'];
        if (task) {
            task.resolve(result);
            worker['busy'] = false;
            worker['currentTask'] = null;
            this.scheduleTask();
        }
    }

    // 处理工作线程错误
    private handleWorkerError(worker: worker.Worker, error: any): void {
        const task = worker['currentTask'];
        if (task) {
            task.reject(error);
            worker['busy'] = false;
            worker['currentTask'] = null;
            this.scheduleTask();
        }
    }

    // 关闭线程池
    public shutdown(): void {
        this.workers.forEach(worker => worker.terminate());
        this.workers = [];
        this.taskQueue = [];
    }
}

实战案例:图片处理应用

下面我们将实现一个图片处理应用,展示如何使用多线程处理大量图片:

import worker from '@ohos.worker';
import image from '@ohos.multimedia.image';
import prompt from '@ohos.prompt';

@Entry
@Component
struct ImageProcessingPage {
    @State images: Array<{
        id: number;
        path: string;
        status: string;
        thumbnail?: image.PixelMap;
    }> = [];
    
    private threadPool: ThreadPool = new ThreadPool(4);
    private asyncTaskManager: AsyncTaskManager = new AsyncTaskManager();

    aboutToAppear() {
        this.initializeThreadPool();
    }

    private initializeThreadPool(): void {
        this.threadPool.initialize();
    }

    build() {
        Column() {
            // 工具栏
            Row() {
                Button('选择图片')
                    .onClick(() => this.selectImages())
                Button('开始处理')
                    .onClick(() => this.processImages())
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceAround)
            .padding(10)

            // 图片网格
            Grid() {
                ForEach(this.images, (img) => {
                    GridItem() {
                        Column() {
                            if (img.thumbnail) {
                                Image(img.thumbnail)
                                    .width('100%')
                                    .aspectRatio(1)
                            } else {
                                LoadingProgress()
                                    .width(40)
                                    .height(40)
                            }
                            Text(img.status)
                                .fontSize(12)
                                .margin({ top: 5 })
                        }
                        .width('100%')
                        .padding(5)
                    }
                })
            }
            .columnsTemplate('1fr 1fr 1fr')
            .width('100%')
            .layoutWeight(1)
        }
        .width('100%')
        .height('100%')
    }

    // 选择图片
    private async selectImages(): Promise<void> {
        // 模拟选择多张图片
        const newImages = Array.from({ length: 6 }, (_, i) => ({
            id: this.images.length + i + 1,
            path: `/images/sample${i + 1}.jpg`,
            status: '等待处理'
        }));
        
        this.images.push(...newImages);
    }

    // 处理图片
    private async processImages(): Promise<void> {
        const tasks = this.images
            .filter(img => img.status === '等待处理')
            .map(img => () => this.processImage(img));

        try {
            await this.asyncTaskManager.executeBatch(tasks, 3);
            prompt.showToast({
                message: '所有图片处理完成'
            });
        } catch (error) {
            console.error('图片处理失败:', error);
            prompt.showToast({
                message: '部分图片处理失败'
            });
        }
    }

    // 处理单张图片
    private async processImage(img: any): Promise<void> {
        try {
            // 更新状态
            img.status = '处理中';

            // 提交图片处理任务到线程池
            const result = await this.threadPool.submitTask({
                type: 'processImage',
                path: img.path
            });

            // 创建缩略图
            img.thumbnail = await this.createThumbnail(result);
            img.status = '已完成';
        } catch (error) {
            img.status = '处理失败';
            throw error;
        }
    }

    // 创建缩略图
    private async createThumbnail(imageData: ArrayBuffer): Promise<image.PixelMap> {
        const imageSource = image.createImageSource(imageData);
        const options = {
            size: { width: 200, height: 200 },
            scaleMode: image.ScaleMode.FIT
        };
        return await imageSource.createPixelMap(options);
    }

    aboutToDisappear() {
        this.threadPool.shutdown();
    }
}

最佳实践与性能优化

  1. 线程管理
  • 合理控制线程数量
  • 及时回收不需要的线程
  • 避免线程饥饿
  1. 任务调度
  • 优先级队列
  • 任务分片
  • 负载均衡
  1. 内存管理
  • 避免内存泄漏
  • 及时释放资源
  • 大对象及时回收

常见问题解决

  1. 线程同步问题
// 线程安全的计数器
class ThreadSafeCounter {
    private count: number = 0;
    private lock: boolean = false;

    public async increment(): Promise<number> {
        while (this.lock) {
            await new Promise(resolve => setTimeout(resolve, 1));
        }
        
        this.lock = true;
        try {
            this.count++;
            return this.count;
        } finally {
            this.lock = false;
        }
    }

    public getValue(): number {
        return this.count;
    }
}
  1. 死锁预防
// 带超时的锁
class TimeoutLock {
    private locked: boolean = false;
    private readonly timeout: number;

    constructor(timeoutMs: number = 5000) {
        this.timeout = timeoutMs;
    }

    public async acquire(): Promise<boolean> {
        const startTime = Date.now();
        
        while (this.locked) {
            if (Date.now() - startTime > this.timeout) {
                throw new Error('获取锁超时');
            }
            await new Promise(resolve => setTimeout(resolve, 1));
        }

        this.locked = true;
        return true;
    }

    public release(): void {
        this.locked = false;
    }
}

总结

本文详细介绍了鸿蒙系统中线程与并发编程的主要内容,包括:

  1. 线程基础知识
  2. Worker线程管理
  3. 异步任务处理
  4. 线程池实现
  5. 实战案例开发

通过本文的学习,开发者可以掌握鸿蒙系统线程与并发编程的核心知识,能够开发出性能优秀、响应迅速的应用程序。在实际开发中,建议结合具体业务需求,合理运用本文介绍的各项技术,同时注意性能优化和资源管理。

你可能感兴趣的:(harmonyos,华为,鸿蒙,多线程,并发,实战,arkts)