Thread στην ανάπτυξη εφαρμογών για κινητά — τι είναι, τύποι και διαχείριση νημάτων

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-03-16 Χρόνος ανάγνωσης: 11 λεπ

Thread — η βασική μονάδα χρόνου επεξεργαστή, που έχει τη δική της στοίβα και εκτελείται ανεξάρτητα από άλλα νήματα. Στην ανάπτυξη εφαρμογών για κινητά, τα νήματα χρησιμοποιούνται για την παράλληλη εκτέλεση εργασιών, ώστε το περιβάλλον να παραμένει αποκριτικό κατά τη διάρκεια μακροχρόνιων λειτουργιών. Το Android υποστηρίζει java.lang.Thread, Executors και Kotlin Coroutines, το iOS — Thread (Objective-C), GCD και OperationQueue. Σύμφωνα με το Android Thread Documentation, η δημιουργία ενός εγγενούς νήματος απαιτεί την εκχώρηση ~1 MB για τη στοίβα από το λειτουργικό σύστημα.

Βασικά σημεία

  • Thread — η ελάχιστη μονάδα προγραμματισμού CPU: κάθε νήμα είναι ανεξάρτητο και έχει τη δική του στοίβα
  • Η δημιουργία νήματος απαιτεί ~1 MB για στοίβα σε Android και 512 KB σε iOS, γι' αυτό τα pools είναι πιο αποδοτικά από την άμεση δημιουργία
  • Android: Thread, Executors, HandlerThread, Coroutines — τέσσερα επίπεδα αφαίρεσης νημάτων
  • iOS: Thread (χαμηλού επιπέδου), GCD (DispatchQueue), OperationQueue (υψηλού επιπέδου)
  • Thread safety — η κοινή πρόσβαση σε mutable δεδομένα απαιτεί συγχρονισμό: locks, atomic, serial queues

Τι είναι το Thread

Thread (νήμα εκτέλεσης) — μια ανεξάρτητη ακολουθία εντολών που το λειτουργικό σύστημα μπορεί να προγραμματίσει σε έναν πυρήνα CPU. Κάθε διεργασία (εφαρμογή) περιέχει τουλάχιστον ένα νήμα — Main Thread. Πρόσθετα νήματα δημιουργούνται για την παράλληλη εκτέλεση εργασιών. Κάθε νήμα έχει τη δική του στοίβα προγράμματος (με τοπικές μεταβλητές), μετρητή εντολών (PC) και καταχωρητές. Η μνήμη heap είναι κοινή για όλα τα νήματα της διεργασίας.

Στα λειτουργικά συστήματα κινητών, τα νήματα προγραμματίζονται με προληπτική πολυεπεξεργασία (preemptive multitasking): το λειτουργικό σύστημα μπορεί να διακόψει την εκτέλεση ενός νήματος ανά πάσα στιγμή και να μεταβιβάσει τον έλεγχο σε άλλο (context switch). Η εναλλαγή περιβάλλοντος είναι δαπανηρή λειτουργία (1–10 μικροδευτερόλεπτα), επειδή απαιτεί αποθήκευση/επαναφορά των καταχωρητών CPU, ενημέρωση του TLB και εκκαθάριση των κρυφών μνημών. Γι' αυτό ακριβώς ο υπερβολικός αριθμός νημάτων (εκατοντάδες και χιλιάδες) υποβαθμίζει την απόδοση — το λειτουργικό σύστημα ξοδεύει περισσότερο χρόνο στην εναλλαγή παρά στην εκτέλεση.

Νήμα και διεργασία είναι διαφορετικές έννοιες. Η διεργασία είναι μια παρουσία της εφαρμογής με αποκλειστική εικονική μνήμη. Το νήμα μέσα στη διεργασία μοιράζεται αυτή τη μνήμη με άλλα νήματα. Στο Android, κάθε στοιχείο της εφαρμογής (Activity, Service, BroadcastReceiver) λειτουργεί σε μία διεργασία, αλλά μπορεί να εκτελείται σε διαφορετικά νήματα. Η εφαρμογή iOS είναι επίσης μία διεργασία με δυνατότητα δημιουργίας πρόσθετων νημάτων μέσω GCD ή Thread.

Κύκλος ζωής νήματος: καταστάσεις και μεταβάσεις

Κάθε νήμα σε Java/Kotlin (Android) και NSThread (iOS) περνά από πέντε καταστάσεις: New (δημιουργήθηκε), Runnable (έτοιμο για εκτέλεση), Running (εκτελείται σε CPU), Blocked/Waiting (περιμένει πόρο ή ειδοποίηση), Terminated (ολοκληρώθηκε). Οι μεταβάσεις μεταξύ των καταστάσεων ελέγχονται από τον χρονοπρογραμματιστή του λειτουργικού συστήματος και τα αρχέγονα συγχρονισμού. Ο προγραμματιστής μπορεί να επηρεάσει την προτεραιότητα του νήματος (Thread.setPriority()) και την κατάστασή του (sleep, join, interrupt).

Στο Android, το νήμα περνά στην κατάσταση Blocked όταν προσπαθεί να καταλάβει έναν κατειλημμένο monitor (synchronized), όταν καλεί Object.wait() ή Thread.sleep(). Στο iOS — όταν καλεί NSCondition.wait(), pthread_cond_wait() ή dispatch_semaphore_wait(). Στην κατάσταση Blocked το νήμα δεν καταναλώνει CPU, αλλά καταλαμβάνει μνήμη (στοίβα). Το νήμα μπορεί να διακοπεί (interrupted) από άλλο νήμα, λαμβάνοντας InterruptedException (Java) ή ελέγχοντας το isCancelled (Kotlin Coroutines).

Κατάσταση Περιγραφή Μέθοδος μετάβασης
New Το νήμα δημιουργήθηκε, αλλά δεν ξεκίνησε Κατασκευαστής Thread()
Runnable Το νήμα είναι έτοιμο για εκτέλεση, περιμένει CPU thread.start()
Running Το νήμα εκτελείται σε πυρήνα CPU Χρονοπρογραμματιστής λειτουργικού συστήματος
Blocked/Waiting Το νήμα περιμένει πόρο, monitor ή ειδοποίηση synchronized, wait(), sleep()
Terminated Το νήμα ολοκλήρωσε το run() ή διακόπηκε run() ολοκληρώθηκε, interrupt()

Context Switch και το κόστος του

Context switch (εναλλαγή περιβάλλοντος) — η λειτουργία κατά την οποία το λειτουργικό σύστημα αποθηκεύει την κατάσταση του τρέχοντος νήματος (καταχωρητές, PC, TLB) και φορτώνει την αποθηκευμένη κατάσταση ενός άλλου. Στα συστήματα κινητών (Linux + ART, XNU για iOS), το context switch διαρκεί 1–10 μικροδευτερόλεπτα. Αν ένα νήμα εκτελεί μια εργασία σε 100 μικροδευτερόλεπτα και το context switch διαρκεί 5, τότε χάνεται το 5% του χρόνου. Για την ελαχιστοποίηση του context switch, το iOS χρησιμοποιεί GCD με work stealing, και το Android — pools με fixedThreadCount.

Thread σε Android: από Thread έως Coroutines

Το Android εξελίχθηκε από το χαμηλού επιπέδου java.lang.Thread στα σύγχρονα coroutines. Κάθε επίπεδο αφαίρεσης δίνει περισσότερες δυνατότητες με μικρότερο πρόσθετο κόστος. Το Thread είναι η βασική κλάση, αλλά η άμεση δημιουργία του δεν συνιστάται: το νέο νήμα δεν διαχειρίζεται από pool, είναι δύσκολο να παρακολουθηθεί και να ακυρωθεί. Το AsyncTask (deprecated από το API 30) ήταν ένα βήμα μπροστά, αλλά υπέφερε από διαρροές μνήμης και μη βολική διαχείριση διαμορφώσεων.

HandlerThread — ειδική υποκλάση του Thread με Looper, που μπορεί να επεξεργάζεται ουρά μηνυμάτων. Χρησιμοποιείται για τη σειριακή εκτέλεση εργασιών σε νήμα παρασκηνίου, για παράδειγμα, εγγραφή δεδομένων σε Room ή αρχεία. Το HandlerThread δημιουργείται με την κλήση start(), μετά την οποία μέσω του Handler(handlerThread.looper) μπορούν να αποσταλούν μηνύματα και Runnable. Η κλήση handlerThread.quit() σταματά το Looper και τερματίζει το νήμα.

kotlin
// Android: Thread, HandlerThread και Executors
import android.os.Handler
import android.os.HandlerThread
import java.util.concurrent.Executors

class ThreadExample {

    // 1. Άμεση δημιουργία Thread (δεν συνιστάται)
    fun directThread() {
        val thread = Thread(Runnable {
            Thread.sleep(1000)
            print("Άμεσο νήμα εκτελέστηκε")
        })
        thread.start()
    }

    // 2. HandlerThread για σειριακές εργασίες παρασκηνίου
    fun handlerThreadExample() {
        val handlerThread = HandlerThread("BackgroundQueue")
        handlerThread.start()

        val handler = Handler(handlerThread.looper)
        handler.post {
            // Σειριακή εκτέλεση σε νήμα παρασκηνίου
            Thread.sleep(500)
            print("HandlerThread: η εργασία ολοκληρώθηκε")
        }

        // Διακοπή νήματος (εκτελείται όταν ολοκληρωθούν οι εργασίες)
        handlerThread.quitSafely()
    }

    // 3. Executors — pool νημάτων
    fun executorExample() {
        val executor = Executors.newFixedThreadPool(4)
        for (i in 1..10) {
            executor.execute {
                print("Task $i on thread ${Thread.currentThread().getName()}")
            }
        }
        executor.shutdown()
    }

    // 4. Kotlin Coroutines — σύγχρονο πρότυπο
    suspend fun coroutineExample() = kotlinx.coroutines.withContext(
        kotlinx.coroutines.Dispatchers.Default
    ) {
        print("Coroutine on thread: ${Thread.currentThread().getName()}")
    }
}

Το παράδειγμα ThreadExample δείχνει και τα τέσσερα επίπεδα αφαίρεσης νημάτων στο Android. Η άμεση δημιουργία Thread είναι η χαμηλότερου επιπέδου και λιγότερο αποδοτική προσέγγιση. Το HandlerThread είναι χρήσιμο για σειριακές εργασίες στο παρασκήνιο. Το Executors.newFixedThreadPool(4) δημιουργεί pool 4 νημάτων για παράλληλη εκτέλεση έως 10 εργασιών. Το Kotlin Coroutines με Dispatchers.Default — σύγχρονος, αποδοτικός και ασφαλής τρόπος.

HandlerThread: σειριακές εργασίες παρασκηνίου

HandlerThread — εξειδικευμένη υποκλάση του Thread με ενσωματωμένο Looper και ουρά μηνυμάτων. Δημιουργείται με την κλήση start(), μετά την οποία μέσω του Handler(handlerThread.looper) μπορούν να αποσταλούν Runnable και μηνύματα. Το HandlerThread εκτελεί τις εργασίες αυστηρά σειριακά — η επόμενη εργασία δεν ξεκινά μέχρι να ολοκληρωθεί η προηγούμενη. Αυτό είναι βολικό για την εγγραφή δεδομένων σε Room ή αρχεία, όπου η σειρά των λειτουργιών είναι κρίσιμη. Η κλήση quitSafely() σταματά το Looper μετά την ολοκλήρωση της τρέχουσας εργασίας.

Thread σε iOS: Thread, GCD και OperationQueue

Το iOS παρέχει επίσης τρία επίπεδα εργασίας με τα νήματα. Thread (Thread σε Swift, NSThread σε Objective-C) — API χαμηλού επιπέδου που δημιουργεί άμεσα εγγενές νήμα. GCD (Grand Central Dispatch) μέσω DispatchQueue — το κύριο εργαλείο για προγραμματιστές iOS, που διαχειρίζεται αυτόματα το pool νημάτων. OperationQueue — αφαίρεση υψηλού επιπέδου πάνω από το GCD με υποστήριξη εξαρτήσεων, προτεραιοτήτων και ακύρωσης.

Η άμεση χρήση του Thread στη σύγχρονη ανάπτυξη iOS είναι εξαιρετικά σπάνια — το GCD παρέχει όλες τις απαραίτητες δυνατότητες με αυτόματη διαχείριση μνήμης και νημάτων. Το Thread χρησιμοποιείται μόνο για συγκεκριμένες περιπτώσεις: ρύθμιση thread-local storage (threadDictionary), δημιουργία RunLoop για νήμα παρασκηνίου ή ενσωμάτωση με βιβλιοθήκες C που περιμένουν pthread_t.

swift
import Foundation

class ThreadManager {

    // 1. Thread (χαμηλού επιπέδου)
    func createThread() {
        let thread = Thread {
            // Ο κώδικας εκτελείται σε νέο νήμα
            print("Current thread: \(Thread.current)")
        }
        thread.name = "com.app.worker"
        thread.qualityOfService = .utility
        thread.start()
    }

    // 2. GCD — DispatchQueue
    func gcdExample() {
        // Παράλληλη ουρά
        let queue = DispatchQueue(label: "com.app.concurrent",
                                 qos: .utility,
                                 attributes: .concurrent)

        queue.async {
            print("Ασύγχρονη εργασία GCD")
        }

        // Barrier για συγχρονισμό εγγραφής
        queue.async(flags: .barrier) {
            // Αποκλειστική πρόσβαση κατά την εγγραφή
            print("Barrier write: αποκλειστική πρόσβαση")
        }
    }

    // 3. OperationQueue με εξαρτήσεις
    func operationQueueExample() {
        let queue = OperationQueue()
        queue.maxConcurrentOperationCount = 2
        queue.qualityOfService = .background

        let download = BlockOperation {
            print("Λήψη...")
        }
        let process = BlockOperation {
            print("Επεξεργασία...")
        }
        let save = BlockOperation {
            print("Αποθήκευση...")
        }

        // Εξαρτήσεις: download -> process -> save
        process.addDependency(download)
        save.addDependency(process)

        queue.addOperations([download, process, save], waitUntilFinished: false)
    }
}

// Thread-safe συλλογή μέσω GCD barrier
class ThreadSafeArray<T> {
    private var array: [T] = []
    private let queue = DispatchQueue(label: "com.app.concurrent",
                                       attributes: .concurrent)

    var count: Int {
        return queue.sync { array.count } // concurrent read
    }

    func append(_ element: T) {
        queue.async(flags: .barrier) { // exclusive write
            self.array.append(element)
        }
    }
}

Η κλάση ThreadSafeArray επιδεικνύει το πρότυπο Concurrent Read / Exclusive Write μέσω GCD barrier. Η ανάγνωση μέσω queue.sync{} εκτελείται παράλληλα από πολλά νήματα. Η εγγραφή μέσω queue.async(flags: .barrier) μπλοκάρει όλες τις άλλες λειτουργίες (τόσο ανάγνωση όσο και εγγραφή) μέχρι να ολοκληρωθεί η εγγραφή. Αυτό είναι πιο αποδοτικό από τα μπλοκ synchronized, επειδή δεν μπλοκάρει τους αναγνώστες όσο δεν υπάρχει εγγραφή.

Thread σε iOS έναντι GCD: πότε να χρησιμοποιείτε απευθείας το Thread

Η άμεση χρήση του Thread στο iOS δικαιολογείται σε τρεις περιπτώσεις: για thread-local storage (Thread.current.threadDictionary) — αποθήκευση δεδομένων που συνδέονται με το νήμα· για τη δημιουργία ειδικού RunLoop σε νήμα παρασκηνίου με performSelector:onThread:· για ενσωμάτωση με βιβλιοθήκες C/C++ που περιμένουν pthread_t. Σε όλες τις άλλες περιπτώσεις, το GCD μέσω DispatchQueue είναι προτιμότερο — διαχειρίζεται αυτόματα το pool νημάτων και την κατανάλωση ενέργειας.

Συγχρονισμός νημάτων: locks, atomic, serial queues

Race condition (συνθήκη ανταγωνισμού) προκύπτει όταν δύο ή περισσότερα νήματα αποκτούν ταυτόχρονα πρόσβαση σε κοινά δεδομένα και τουλάχιστον ένα από αυτά εκτελεί εγγραφή. Το αποτέλεσμα εξαρτάται από τη σειρά εκτέλεσης (timing) και είναι απρόβλεπτο. Για την πρόληψη της race condition χρησιμοποιούνται αρχέγονα συγχρονισμού. Στην ανάπτυξη εφαρμογών για κινητά διατίθενται κλειδώματα (synchronized, NSLock), ατομικές λειτουργίες (AtomicInteger, ιδιότητες atomic στο iOS) και ουρές (serial queue).

Η επιλογή του αρχέγονου εξαρτάται από το σενάριο. Για απλούς μετρητές και σημαίες αρκούν οι ατομικές λειτουργίες (AtomicInteger, atomic property). Για κρίσιμα τμήματα με πολλές λειτουργίες — τα κλειδώματα (synchronized, NSLock). Για πολύπλοκες δομές δεδομένων — serial DispatchQueue ή GCD barrier. Τα κλειδώματα είναι πιο εύκολα στην κατανόηση, αλλά είναι επιρρεπή σε deadlock και livelock. Οι ουρές είναι πιο πολύπλοκες, αλλά πιο ασφαλείς.

kotlin
// Συγχρονισμός σε Android/Kotlin
import java.util.concurrent.atomic.AtomicInteger
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

class Counter {

    // 1. AtomicInteger — για απλούς μετρητές
    private val atomicCount = AtomicInteger(0)
    fun incrementAtomic() = atomicCount.incrementAndGet()

    // 2. synchronized — για κρίσιμα τμήματα
    @Synchronized
    fun synchronizedOperation() {
        // Μόνο ένα νήμα τη φορά
        doWork()
    }

    // 3. Mutex από coroutines — suspend-safe
    private val mutex = Mutex()
    suspend fun mutexOperation() {
        mutex.withLock {
            // protected code — thread-safe
            doWork()
        }
    }

    private fun doWork() { /* critical section */ }
}

// Παράδειγμα deadlock: A μπλοκάρει το B, B μπλοκάρει το A
class DeadlockExample {
    private val lockA = Any()
    private val lockB = Any()

    fun methodA() = synchronized(lockA) {
        Thread.sleep(100)
        synchronized(lockB) { print("OK") }
    }

    fun methodB() = synchronized(lockB) {
        Thread.sleep(100)
        synchronized(lockA) { print("OK") }
    }
}

Ο Counter επιδεικνύει τρεις προσεγγίσεις συγχρονισμού. AtomicInteger.incrementAndGet() — ατομική λειτουργία χωρίς κλειδώματα (CAS). @Synchronized — ο ενσωματωμένος monitor της Java, μπλοκάρει ολόκληρο το αντικείμενο. Mutex.withLock — coroutine mutex, αναστέλλει το coroutine αντί να μπλοκάρει το νήμα (πιο αποδοτικό). Το DeadlockExample δείχνει ένα κλασικό deadlock: δύο νήματα αποκτούν τα κλειδώματα με διαφορετική σειρά.

Thread Pools: γιατί το Executors είναι καλύτερο από το Thread

Thread Pool (pool νημάτων) — ένα σύνολο προδημιουργημένων νημάτων που επαναχρησιμοποιούνται για την εκτέλεση εργασιών. Αντί να δημιουργείται νέο νήμα για κάθε εργασία (δαπανηρό), το pool παίρνει ένα ελεύθερο νήμα από το pool. Αν δεν υπάρχουν ελεύθερα νήματα, η εργασία μπαίνει σε ουρά. Το pool διαχειρίζεται αυτόματα το μέγεθος: νέα νήματα δημιουργούνται σε αιχμές φόρτου, τα αδρανή νήματα τερματίζονται. Αυτό μειώνει το κόστος δημιουργίας νημάτων δεκαπλασίως.

Στο Android, το Executors.newFixedThreadPool(4) δημιουργεί pool 4 νημάτων. Αν έρθουν ταυτόχρονα 10 εργασίες, οι 4 θα ξεκινήσουν αμέσως και οι 6 θα περιμένουν στην ουρά. Το Executors.newCachedThreadPool() δημιουργεί νήματα ανάλογα με τις ανάγκες (χωρίς όριο) και τερματίζει τα αδρανή μετά από 60 δευτερόλεπτα. Για το iOS, το GCD παρέχει αυτόματα pools καθολικών ουρών, το μέγεθος των οποίων αντιστοιχεί στον αριθμό των πυρήνων CPU και στο τρέχον φορτίο.

Στα Kotlin Coroutines, τα pools νημάτων είναι κρυμμένα μέσα στους dispatchers. Το Dispatchers.Default χρησιμοποιεί pool μεγέθους ίσου με τον αριθμό των πυρήνων CPU (τουλάχιστον 2). Το Dispatchers.IO — 64 νήματα (αρκετά για εκατοντάδες εργασίες IO-bound, καθώς οι περισσότερες θα περιμένουν είσοδο-έξοδο χωρίς να καταλαμβάνουν CPU). Κάθε dispatcher κλιμακώνει αυτόματα το pool ανάλογα με το φορτίο, εξοικονομώντας ενέργεια μπαταρίας σε κατάσταση αδράνειας.

Συχνές ερωτήσεις

Τι είναι το Thread στην ανάπτυξη εφαρμογών για κινητά;

Thread — η βασική μονάδα εκτέλεσης κώδικα σε μια εφαρμογή. Κάθε διεργασία μπορεί να έχει πολλά νήματα που μοιράζονται τη μνήμη, αλλά με δική τους στοίβα. Στην ανάπτυξη εφαρμογών για κινητά, τα νήματα χρησιμοποιούνται για παράλληλη εκτέλεση εργασιών χωρίς μπλοκάρισμα του UI. Το Android χρησιμοποιεί Thread, Executors, HandlerThread και Coroutines. Το iOS χρησιμοποιεί Thread, GCD (DispatchQueue) και OperationQueue.

Γιατί δεν συνιστάται η άμεση δημιουργία Thread;

Η δημιουργία Thread απαιτεί εκχώρηση ~1 MB για στοίβα σε Android και ~512 KB σε iOS — είναι δαπανηρή λειτουργία. Για 1000 εργασίες, η άμεση δημιουργία 1000 νημάτων θα απαιτήσει ~1 GB μόνο για τις στοίβες συν το πρόσθετο κόστος για context switch. Αντί για Thread, χρησιμοποιήστε pools (Executors, GCD) ή coroutines — επαναχρησιμοποιούν τα νήματα, μειώνοντας το κόστος δεκαπλασίως.

Τι είναι η race condition και πώς να την αποφύγετε;

Race condition — απρόβλεπτη συμπεριφορά όταν πολλά νήματα αποκτούν ταυτόχρονα πρόσβαση σε κοινά δεδομένα με εγγραφή. Μπορεί να αποφευχθεί με τρεις τρόπους: χρήση ατομικών τύπων (AtomicInteger), κλειδωμάτων (synchronized, NSLock) ή σειριοποίηση της πρόσβασης μέσω ουράς (serial DispatchQueue, Actor σε Kotlin). Βέλτιστη πρακτική — ελαχιστοποίηση της κοινής mutable κατάστασης και χρήση immutability.

Ποια η διαφορά μεταξύ Thread και coroutine;

Thread — εγγενές αντικείμενο συστήματος που καταλαμβάνει ~1 MB στοίβας και συνδέεται με τον πυρήνα του λειτουργικού συστήματος. Coroutine — ελαφριά μονάδα εκτέλεσης στο Kotlin που δεν συνδέεται με συγκεκριμένο νήμα και μπορεί να ανασταλεί (suspend) χωρίς μπλοκάρισμα. Ένα νήμα μπορεί να εκτελεί χιλιάδες coroutines. Τα coroutines είναι πιο αποδοτικά στη μνήμη και επιτρέπουν την εγγραφή ασύγχρονου κώδικα χωρίς callbacks.

Πώς να εντοπίσετε το deadlock σε μια εφαρμογή για κινητά;

Deadlock εκδηλώνεται ως πλήρες πάγωμα της εφαρμογής χωρίς ANR. Στο Android χρησιμοποιήστε Thread.getAllStackTraces() για dump των στοιβών όλων των νημάτων — δύο νήματα θα περιμένουν τα κλειδώματα το ένα του άλλου. Στο iOS — Thread.callStackSymbols. Εργαλεία: Android Studio Profiler (καρτέλα Threads), Instruments (iOS, Thread State View). Πρόληψη: αποκτάτε τα κλειδώματα με σταθερή σειρά, χρησιμοποιήστε tryLock με χρονικό όριο.

Συμπεράσματα

  • Thread — η ελάχιστη μονάδα CPU: ανεξάρτητη εκτέλεση με δική της στοίβα, η μνήμη heap είναι κοινή
  • Πέντε καταστάσεις νήματος: New, Runnable, Running, Blocked/Waiting, Terminated
  • Android εξελίχθηκε από Thread → AsyncTask → Executors → HandlerThread → Coroutines
  • iOS παρέχει Thread, GCD (DispatchQueue) και OperationQueue — από χαμηλό σε υψηλό επίπεδο
  • Race condition λύνεται με κλειδώματα (synchronized, NSLock), ατομικούς τύπους και σειριακές ουρές
  • Deadlock προκύπτει κατά τη διασταυρούμενη απόκτηση κλειδωμάτων — αποτρέπεται με σταθερή σειρά
  • Thread Pool είναι πιο αποδοτικό από τη δημιουργία νέων Thread: επαναχρησιμοποιεί νήματα, μειώνει το κόστος του context switch

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης