← Back to list

Running Heavy Tasks on Worker Threads in HarmonyOS NEXT Without Blocking the UI

In this article, we’ll explore how to safely move heavy tasks to worker threads, design thread-safe shared singletons.

Arif Emre Ankara in Huawei Developers · 2025-12-25 07:23 · 100 claps · 3.5 min read
#huawei #harmony-os #ark-ts #harmonyos-next #ark-ui
Open on Medium ↗
Wiki topics: 🏃 · Running & Endurance

Running Heavy Tasks on Worker Threads in HarmonyOS NEXT Without Blocking the UI

Image is generated with AI

Image is generated with AI

In this article, we’ll explore how to safely move heavy tasks to worker threads, design thread-safe shared singletons, and ensure smooth UI performance without interruptions.

Introduction

Modern mobile applications frequently deal with heavy operations such as JSON parsing, network requests, database access, and shared state management. If these tasks run on the main thread, the result is inevitable: UI freezes, dropped frames, and poor user experience.

HarmonyOS NEXT provides worker threads to solve this problem — but with important constraints.

The Core Requirement

The goal is simple but non-trivial:

Move time-consuming tasks (JSON parsing, HTTP processing, singleton access, observers, event handling) off the main thread while preserving correctness and stability.

Specifically, we want to:

  • Avoid UI lag
  • Respect HarmonyOS worker-thread limitations
  • Share state safely across threads
  • Maintain singleton uniqueness
  • Prevent data races

Understanding Worker Thread Limitations in HarmonyOS NEXT

Thread loop

Thread loop

Unlike the main thread, worker threads in HarmonyOS NEXT are restricted environments.

What You Cannot Do in Worker Threads

  • UI updates
  • Context-dependent APIs
  • dbStore operations
  • preferences
  • eventHub
  • Observer-based UI state updates

These APIs are not thread-safe and must remain on the main thread.

What You Can Do

  • JSON parsing
  • Data transformation
  • Calculations
  • Validation logic
  • Business rules
  • Stateless processing

The key idea: Split computation from side effects

Design Strategy: Main Thread + Worker Thread Cooperation

The recommended architecture looks like this:

  • Worker thread
  • Heavy computation
  • Parsing
  • Data preparation
  • Main thread
  • UI updates
  • Database writes
  • Event dispatch
  • Context-based logic

This separation ensures performance and stability.

Cross-Thread Singletons: The Right Way

Sharing state across threads introduces complexity. HarmonyOS NEXT solves this with:

  • “use shared” modules
  • @Sendable classes
  • Explicit synchronization

Key Rules

  1. Shared singletons must live in a shared module
  2. Classes must be marked with @Sendable
  3. Mutable state must be protected with locks

Thread Safety with AsyncLock

Multiple Threading

Multiple Threading

When multiple threads modify the same data, race conditions become inevitable unless guarded.

HarmonyOS provides ArkTSUtils.locks.AsynLock to ensure exclusive access to shared state.

Example: @Sendable Singleton Shared Across Threads

Below is a production-safe demo illustrating:

  • A singleton shared across worker & main threads
  • Locked access to mutable fields
  • Guaranteed data consistency
import { ArkTSUtils , collections } from '@kit.ArkTS';
// Declare that the current module is a shared module and can only export Sendable data
"use shared"
// Shared module, TestData is globally unique
@Sendable
export class TestData {
  private keyHandle: string = '0';
  private count_: number = 0;
  private arr: collections.Array<number> = new collections.Array<number>();
  private isLoadingShowing: boolean = false;
  lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock()
  private static instance: TestData;
  private constructor() {}
  public static getInstance(): TestData {
    if (TestData.instance == null) {
      TestData.instance = new TestData();
      console.debug('getInstance new')
    }
    return TestData.instance;
  }
  getLoadingShowing(): boolean {
    return this.isLoadingShowing;
  }
  setLoadingShowing(isShow: boolean) {
    this.isLoadingShowing = isShow
  }
  async getKeyHandle(): Promise<string> {
    return this.lock_.lockAsync(() => {
      return this.keyHandle;
    })
  }
  async setKeyHandle(keyHandle: string) {
    await this.lock_.lockAsync(() => {
      this.keyHandle = keyHandle;
    })
  }
  public async getCount(): Promise<number> {
    return this.lock_.lockAsync(() => {
      return this.count_;
    })
  }
  public async increaseCount() {
    await this.lock_.lockAsync(() => {
      this.count_++;
    })
  }
  public async getArr(): Promise<collections.Array<number>> {
    return this.lock_.lockAsync(() => {
      return this.arr;
    })
  }
  public async setArr(arr: collections.Array<number>) {
    return this.lock_.lockAsync(() => {
      this.arr = arr;
    })
  }
}

What This Example Demonstrates

  • Singleton uniqueness across threads
  • Safe concurrent access
  • No race conditions
  • Worker-thread-compatible design
  • UI remains responsive

Test Results

The implementation was validated under real conditions:

  • Multiple worker threads accessing the singleton
  • Concurrent reads and writes
  • Heavy computation off the main thread

Observed Behavior

  • No UI freezes
  • State remains consistent
  • AsyncLock prevents data corruption
  • Singleton instance remains unique across threads

Important Considerations & Pitfalls

Before applying this pattern broadly, keep these in mind:

  • ❗ dbStore, preferences, eventHub must stay on the main thread
  • ❗ Worker threads do not automatically inherit context
  • ❗ @sendable and “use shared” are mandatory
  • ❗ Refactoring is often required when logic mixes UI + computation

Conclusion

Worker threads are essential for building smooth, responsive HarmonyOS NEXT applications — but only when used correctly.

By:

  • Separating computation from side effects
  • Designing shared, @Sendable singletons
  • Protecting state with AsyncLock

you can safely unlock high-performance background processing without sacrificing correctness or user experience.

When Should You Use This Pattern?

✔ Large JSON parsing ✔ Heavy calculations ✔ Shared state accessed by background tasks ✔ Performance-sensitive UI ✔ Scalable architecture design

REFERENCES

[embed]HUAWEI Developer Forum | HUAWEI Developer Edit descriptionforums.developer.huawei.com


메타데이터
post_id
697d8c430ee8
slug
running-heavy-tasks-on-worker-threads-in-harmonyos-next-without-blocking-the-ui-697d8c430ee8
url
https://medium.com/huawei-developers/running-heavy-tasks-on-worker-threads-in-harmonyos-next-without-blocking-the-ui-697d8c430ee8
canonical_url
https://medium.com/huawei-developers/running-heavy-tasks-on-worker-threads-in-harmonyos-next-without-blocking-the-ui-697d8c430ee8
author_url
https://medium.com/@ankaraarifemre
status
ok
fetched_at
2026-07-13 22:58:47