1. Auto.js多线程基础入门第一次接触Auto.js多线程时我也被各种概念搞得晕头转向。为什么需要多线程简单来说就像餐厅里一个服务员同时要招呼客人、传菜、收银单线程处理会让顾客等得抓狂。多线程就是让多个服务员各司其职效率自然翻倍。在Auto.js中所有脚本默认运行在主线程。当我们需要同时执行UI操作、网络请求和数据处理时单线程就会遇到瓶颈。比如监控UI变化的同时还要定期请求服务器数据单线程只能做完一件再做另一件而多线程可以让它们并行处理。先看个最简单的多线程例子// 主线程任务 console.log(主线程开始); // 启动子线程1 threads.start(function(){ while(true){ console.log(子线程1执行中); sleep(1000); } }); // 主线程继续执行 console.log(主线程结束);运行后会看到主线程的日志先输出然后子线程的日志持续每秒输出。这就是多线程最基本的特性——非阻塞执行。需要注意几个关键点主线程不会等待子线程结束子线程与主线程共享脚本上下文所有线程默认会随脚本结束而终止2. 多线程核心API详解2.1 线程生命周期管理创建线程最常用的就是threads.start()但实际开发中我们还需要更精细的控制// 创建可管理的线程实例 const worker threads.start(function(){ console.log(子线程启动); while(!threads.currentThread().isInterrupted()){ // 执行任务 sleep(1000); } console.log(子线程结束); }); // 等待线程启动 worker.waitFor(); // 停止线程的两种方式 worker.interrupt(); // 优雅停止 // threads.shutDownAll(); // 强制停止所有线程这里有几个实用技巧waitFor()确保线程真正启动后再进行后续操作isInterrupted()检查中断标志实现优雅退出区别使用interrupt()和shutDownAll()2.2 线程间同步控制当多个线程需要协作时同步就变得至关重要。比如一个线程处理UI另一个线程获取数据数据就绪后才更新UIconst lock threads.lock(); let dataReady false; // 数据线程 threads.start(function(){ // 模拟数据获取 sleep(2000); lock.lock(); try { dataReady true; } finally { lock.unlock(); } }); // UI线程 threads.start(function(){ lock.lock(); try { while(!dataReady) { lock.wait(); } console.log(开始更新UI); } finally { lock.unlock(); } });这种生产者-消费者模式在实际开发中非常常见。关键点使用threads.lock()创建锁对象临界区代码要用lock()/unlock()包裹wait()/notify()用于线程间通信3. 复杂场景实战技巧3.1 定时任务管理定时器在多线程环境下需要特别注意执行上下文。比如这个电商抢购场景// 主线程设置抢购时间 const buyTime new Date(2023-12-31 20:00:00).getTime(); // 监控线程 const monitor threads.start(function(){ setInterval(function(){ const now new Date().getTime(); if(now buyTime) { threads.start(function(){ // 执行抢购逻辑 console.log(开始抢购); }); clearInterval(this); } }, 100); }); // UI保持响应 threads.start(function(){ while(true){ // 更新倒计时UI sleep(1000); } });这种设计实现了精确到毫秒级的定时触发不阻塞UI刷新抢购逻辑在独立线程执行3.2 异常处理机制多线程环境下异常处理需要特别设计。推荐的做法// 全局异常处理器 threads.setDefaultUncaughtExceptionHandler(function(e){ console.error(全局捕获:, e); }); // 带异常保护的线程 const safeThread threads.start(function(){ try { // 业务代码 while(true){ maybeErrorOperation(); sleep(1000); } } catch(e) { console.error(线程内部捕获:, e); // 可以选择重启线程 } }); // 添加线程专属异常处理器 safeThread.setUncaughtExceptionHandler(function(t, e){ console.error(线程${t}出错:, e); });这种分层异常处理机制能确保线程内部异常不会导致整个脚本崩溃可以针对不同线程定制处理逻辑支持异常后自动恢复4. 性能优化与调试4.1 线程池模式频繁创建销毁线程开销很大可以采用线程池模式const threadPool { _pool: [], _taskQueue: [], init(size) { for(let i0; isize; i){ this._pool.push(this._createWorker()); } }, _createWorker() { const thread threads.start(function(){ while(true){ const task threads.wait(this, newTask); try { task.func.apply(null, task.args); } catch(e) { console.error(e); } } }); thread.isIdle true; return thread; }, execute(func, ...args) { const idleThread this._pool.find(t t.isIdle); if(idleThread) { idleThread.isIdle false; idleThread.post(newTask, {func, args}); } else { this._taskQueue.push({func, args}); } } }; // 初始化4个线程 threadPool.init(4); // 使用示例 for(let i0; i10; i){ threadPool.execute(function(num){ console.log(处理任务num); sleep(1000); }, i); }这种实现控制最大线程数避免资源耗尽任务队列保证不会丢失请求线程复用减少创建开销4.2 常见问题排查多线程调试确实比较困难分享几个实用技巧线程卡死检测function watchDog(timeout 5000) { const timer setTimeout(() { console.trace(看门狗触发); threads.shutDownAll(); }, timeout); return { feed() { clearTimeout(timer); this.timer setTimeout(() { console.trace(看门狗触发); threads.shutDownAll(); }, timeout); } }; } // 使用示例 const dog watchDog(); threads.start(function(){ while(true){ doWork(); dog.feed(); // 定期喂狗 sleep(1000); } });性能分析标记console.time(关键操作); // ...执行代码 console.timeEnd(关键操作);线程安全检查清单共享数据是否加锁是否存在竞态条件异常是否妥善处理资源是否及时释放