Processi e discussioni: lavorare da soli e utilizzare le memorie di sé

📖 11min read

Conoscenze come 1 minuto di autopresentazione per il colloquio

“Qual è la differenza tra un processo e un thread?”

Quando ero in cerca di lavoro, questa domanda era sempre inclusa nelle “10 domande più comuni nei colloqui”. Ho risposto come una macchina.

“Un processo è un programma in esecuzione e un thread è un’unità di flusso che viene eseguita all’interno di un processo. I processi non condividono risorse, ma i thread condividono risorse.”

L’intervistatore ha annuito e ho pensato di aver capito perfettamente questo concetto. Tuttavia, finché non ho riscontrato nella pratica il “problema di concorrenza”, non avevo idea della vera paura contenuta in quella frase.

“Perché il numero di visualizzazioni dovrebbe aumentare di 100, ma aumenta solo di 98?” “Perché il sito web si blocca quando scarico Excel?”

Il mio codice era perfetto quando lo eseguivo da solo, ma diventava un disastro quando entravano più utenti contemporaneamente. Pensavo che il problema si sarebbe risolto semplicemente aumentando il numero di “lavoratori”, ma non sapevo che all’aumentare del numero di lavoratori, il costo della loro gestione (cambio di contesto) aumenta in modo esponenziale.

Quando lavori da solo, è tutto pacifico, ma quando lavori con gli altri, inizia la guerra.

Fabbrica e lavoratori nel centro logistico digitale

Torniamo alla nostra visione del mondo del “centro logistico digitale”. Eseguire un programma su un computer è come creare una “fabbrica” in un centro di distribuzione.

1. Processo: luogo di lavoro indipendente

2. Discussione: Lavoratori in officina

I thread hanno sia uno “spazio condiviso (heap)” che uno “spazio indipendente (stack)”.

[Verifica del codice] Tragedia della condivisione (problema di concorrenza)

“I thread condividono risorse.” Questo può sembrare un vantaggio nella stanza dei colloqui, ma in pratica può essere il seme di un “disastro”.

Ricordi l'”Heap” che abbiamo imparato l’ultima volta? I thread condividono questa area heap. Ciò significa che il thread B può arrivare e sovrascrivere i dati su cui sta lavorando il thread A.

Questa si chiama “Race Condition”. Controlliamolo con il codice.

public class RaceConditionTest {
    static int count = 0; // Variabile condivisa memorizzata nello Heap

    public static void main(String[] args) throws InterruptedException {
        // Assumere due lavoratori (thread)
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) count++;
        });
        
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) count++;
        });

        t1.start(); // Iniziare il lavoro!
        t2.start(); // Iniziare il lavoro!
        
        t1.join(); // Attendere finche non finisce il turno
        t2.join(); // Attendere finche non finisce il turno
        
        System.out.println("Risultato finale: " + count);
    }
}

Risultato previsto: poiché due persone hanno sommato 10.000 volte, il risultato dovrebbe essere 20.000.

Risultato effettivo: 15.482, 18.931… Il valore è diverso ogni volta che lo eseguo e 20.000 non viene visualizzato.

Motivo:

Questa è l’identità del bug che in pratica “a volte i dati vengono masticati”. Questa è una tragedia che si è verificata quando i lavoratori hanno toccato lo stesso registro senza parlarsi.

Se confrontiamo questa situazione con un database (DB), è come “una situazione in cui più query vengono eseguite simultaneamente senza una transazione”. Se contemporaneamente il saldo del conto bancario viene modificato senza blocco, si verifica un terribile incidente in cui il denaro evapora. Proprio come proteggiamo i dati nel DB con ROLLBACK o COMMIT, così a livello di codice è assolutamente necessario un dispositivo di blocco come Synchronized.

Compromesso in pratica: multiprocesso vs. multithread

Quindi quando e cosa dovresti usare nella pratica?

1. Browser Chrome preferito: multiprocesso

Nel vecchio Internet Explorer, quando si interrompeva una scheda, l’intero browser si chiudeva (metodo multi-thread). Tuttavia, Chrome avvia ciascuna scheda come un “processo separato (fabbrica)”.

2. Scelta del server web (Spring, Node.js, ecc.): Multi-thread

Il server deve gestire migliaia di richieste. Se crei un processo (factory) per ogni richiesta, il server si bloccherà. Pertanto, viene elaborato avendo numerosi thread (worker) in un unico processo.

Preferiresti costruire una “fortezza” sicura ma costosa o pilotare un “drone” veloce ma pericoloso?

Conclusione: l’autoimmolazione comporta responsabilità

Oggi abbiamo esaminato “processi e thread”, il modo in cui lavorano i lavoratori.

Ora sai che il termine “problemi di concorrenza” non è solo un termine da intervista. Numerosi threadworker si muovono costantemente dentro e fuori da un magazzino condiviso chiamato Heap. È l’abilità di uno sviluppatore back-end creare ordine in questo caos.

Ma aspetta, se ci sono molti lavoratori, come decidi chi dovrebbe fare per primo il lavoro di chi? Come fa un direttore di fabbrica (OS) a gestire centinaia di lavoratori? La prossima volta parleremo del compito più problematico del direttore di fabbrica, “Programmazione e cambio di contesto”.

Lascia un commento