Leggi prima questo:
Eric Lippert ha già scritto un'ottima risposta su Stack Overflow che dovrebbe anche rispondere alla tua domanda: Qual è la differenza tra la programmazione asincrona e il multithreading?
TL; DR
La tua impressione è giusta; il multi-threading non migliorerebbe gli aspetti prestazionali delle attività legate all'IO.
Ciò che dice l'autore Java (come citato da OP) , mentre non migliorerebbe le prestazioni, riduce la complessità del tuo codice.
Obiettivi diversi, conclusioni diverse.
La mia risposta si concentra sull'uso della terminologia e il problema della confusione.
Ci sono diversi livelli di "can" . Il primo è il meno generalizzabile e il terzo è il più generalizzabile.
- Che è possibile a tutti
- (vale a dire senza considerare meriti e sforzi)
- È vantaggioso farlo in base a criteri specifici
- (ad esempio in grado di ridurre i tempi di completamento sfruttando i core CPU inutilizzati)
- Che è generalmente raccomandato per le situazioni date dopo aver preso in considerazione un'ampia gamma di criteri
- (cioè c'è un elenco di criteri di accompagnamento considerato)
- (ma, fa anche molte supposizioni su "il caso / i bisogni generali", il che significa che qualcuno con un requisito insolito potrebbe trovarlo non applicabile.)
Quando si menzionano "task mutualmente esclusivi", un modo migliore per dire che si tratta di attività che possono essere eseguite indipendentemente e che non ostacolano e / o interferiscono reciprocamente quando vengono eseguite simultaneamente (come in più core CPU) o contemporaneamente ("sovrapposti" o "in modo asincrono" o "commutazione di attività").
È sempre possibile, e di solito è vantaggioso, avere attività eseguibili in modo indipendente eseguite su più CPU. L'eccezione a questa regola è se le attività sono troppo piccole, quindi i costi generali (soprattutto il tempo di attesa dovuto alla consegna di attività e risultati tra le CPU) potrebbero rovinare i risparmi.
Asincrono è un aggettivo che significa grosso modo punteggiato. Significa che un'attività non viene eseguita continuamente. Passa da esecuzione a pausa (blocco). In generale sta gradualmente progredendo verso l'obiettivo (completamento).
Asincrono può riferirsi a:
- Lo stile di codifica,
- Funzioni sintattiche e di generazione del codice fornite da un linguaggio di programmazione,
- Il modo generale in cui viene eseguito un compito di livello superiore, un fatto che deve essere giudicato in modo soggettivo.
Quando la programmazione asincrona viene eseguita su un linguaggio di programmazione che non fornisce il miglior zucchero sintattico, il risultato è un codice più complicato che è più difficile da capire, mantenere e risolvere. Pertanto, viene fornito con il consiglio (o, una pausa dal consiglio generale) che, se la complessità del codice è troppo alta, allora è consigliabile per uno abbandonare il tentativo di programmazione asincrona e tornare ad un stile di codifica sincrono.
Se la lingua fornisce molto zucchero sintattico per essa, allora è possibile programmare molto in stile di programmazione asincrona senza subire la complessità del codice.
Il codice asincrono non è richiesto per essere a thread singolo. Infatti, in C # è possibile combinare la programmazione asincrona e il multithreading (*), come spiegato nella risposta di Eric Lippert (vedere la parte superiore della risposta per il collegamento).
(*) Crea solo un "come faccio a tornare al chiamante" / "codice in esecuzione sul thread sbagliato" diavolo. Per questo motivo si consiglia di avere un "master thread" incaricato di delegare le attività e questo "master thread" implementerà un ciclo di eventi, che è il meccanismo tramite il quale riceverà invocazione, comunicazione e completamento della procedura da altre attività o thread di lavoro.
A volte è possibile scegliere un'architettura asincrona e single-threaded a causa delle limitazioni tecniche di una o più librerie o framework che utilizza. Ad esempio, quando si programma su Windows, la GUI è in genere a thread singolo, il che significa che non è thread-safe per essere invocato da un thread che non è il thread principale.
La parola "I / O bound" è di solito un termine improprio. Fondamentalmente significa "compiti che richiedono tempo per finire ma non sono vincolati alla CPU".
Ad esempio, un'attività che a volte viene detta "vincolata I / O" implica solo un po 'di trasmissione dei dati. Ad esempio, i dati vengono sottoposti a crunch su un server remoto; l'attività del computer locale è semplicemente in attesa che il server remoto pronunci "done".