Optimizing Mobile App Threads and Concurrency

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Optimizing Mobile App Threads and Concurrency
Complex
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Mobile Application Threads and Concurrency Optimization

Deadlock in iOS application reproduces unstably: once every 20–30 minutes application hangs completely. Crash logs contain nothing, because this is not a crash, it's a deadlock. Thread state dump through Xcode shows: main thread blocked on DispatchQueue.sync to SerialQueue, and SerialQueue waits for completion handler trying to execute on main thread. Classic two-thread deadlock.

Concurrency — one of most complex topics in mobile development. Data races, deadlocks, UI updates from wrong thread — these errors appear rarely, reproduce unstably and cost dear in production.

Typical Thread Problems

UI Updates from Wrong Thread

On Android: CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. Cause — processing network response directly in Retrofit callback without withContext(Dispatchers.Main).

On iOS: Main Thread Checker in Xcode (enabled by default in Scheme settings) catches UIKit access from background threads in debug builds. In release — random crashes or visual corruption.

Correct iOS pattern:

DispatchQueue.global(qos: .userInitiated).async {
    let result = heavyComputation()
    DispatchQueue.main.async {
        self.label.text = result // only here
    }
}

Thread Explosion with GCD

DispatchQueue.global().async creates new thread on each call if all worker threads busy. At 64+ simultaneous async tasks, system starts creating threads aggressively — this is thread explosion. Symptom: everything works fine, then sharp performance degradation under load.

Solution: limited concurrency through OperationQueue.maxConcurrentOperationCount or through Swift Concurrency TaskGroup with explicit withTaskGroup and limited parallelism:

await withTaskGroup(of: Result.self) { group in
    for item in items.prefix(4) { // no more than 4 parallel tasks
        group.addTask { await process(item) }
    }
}

Data Races

Multiple threads read and write same field without synchronization. On Swift — Thread Sanitizer (TSan) finds data races in debug builds. Enabled in Scheme → Diagnostics → Thread Sanitizer.

Synchronization options:

  • NSLock / os_unfair_lock — fast mutexes for critical sections
  • DispatchQueue(label:attributes:.concurrent) with barrier for read-write lock pattern
  • actor in Swift 5.5+ — most modern way, compiler guarantees data isolation
actor UserCache {
    private var storage: [String: User] = [:]

    func get(_ id: String) -> User? { storage[id] }
    func set(_ user: User) { storage[user.id] = user }
}

With actor compiler won't allow accessing storage outside actor-context without await.

Android: Incorrect Coroutines Usage

GlobalScope.launch — red flag. Coroutine lives infinitely, doesn't cancel when screen closes. On re-open — second one created. Correct — viewModelScope.launch (cancels on onCleared) or lifecycleScope.launch (cancels on onDestroy).

Dispatchers.Main vs Dispatchers.Main.immediate: when called from main thread, Dispatchers.Main.immediate executes synchronously without context switch — important for animations and immediate UI updates.

Improper exception handling in coroutines:

// WRONG — exception won't be caught
scope.launch {
    try { riskyOperation() } catch (e: Exception) { handle(e) }
}

// CORRECT — CoroutineExceptionHandler for structured handling
val handler = CoroutineExceptionHandler { _, e -> handleError(e) }
scope.launch(handler) { riskyOperation() }

Diagnostics Tools

Tool Platform What It Finds
Thread Sanitizer (TSan) iOS / Android Data races
Main Thread Checker iOS UI from background thread
Instruments → Time Profiler iOS Blocked threads
Android Studio Profiler → Threads Android Thread states, sleep/block/run
StrictMode Android Disk/network on main thread
Kotlin Coroutines Debugger Android Active coroutines, their stacks

StrictMode on Android — enable in debug build:

StrictMode.setThreadPolicy(
    StrictMode.ThreadPolicy.Builder()
        .detectDiskReads().detectNetworkOnMainThread()
        .penaltyLog().penaltyFlashScreen()
        .build()
)

Screen flashing on violation — impossible to ignore.

Case: Deadlock in Swift

E-commerce application: adding to cart UI sometimes froze for 30–60 seconds. Reproduced only on poor internet.

Through Thread State dump found: CartService.addItem() called userDefaults.synchronize() inside serialQueue.sync, and synchronize() inside waited NSFileCoordinator, also standing in write queue. With network delay, several addItem() calls lined up and one fell into deadlock with NSFileCoordinator.

Solution: removed synchronize() (no-op in iOS 12+), moved cart saving to async write through DispatchQueue.global().async.

Work Stages

  1. Enable TSan and Main Thread Checker on all test runs
  2. Analyze Thread state in Instruments / Android Profiler Threads view
  3. Check all places with sync calls and shared mutable state
  4. Fix: weak references, correct dispatch queues, actor isolation
  5. Load testing to reveal race conditions under stress

Timeframe

Concurrency audit — 2–4 days. Fixing found issues — 3–14 days depending on depth of architectural decisions.