Processen en onderwerpen: alleen werken versus het gebruik van zelfmemoires

📖 11min read

Kennis zoals 1 minuut zelfintroductie voor een interview

“Wat is het verschil tussen een proces en een thread?”

Toen ik werkzoekende was, stond deze vraag altijd in de ‘Top 10 veelgestelde sollicitatievragen’. Ik antwoordde als een machine.

“Een proces is een actief programma en een thread is een stroomeenheid die wordt uitgevoerd binnen een proces. Processen delen geen bronnen, maar threads delen bronnen.”

De interviewer knikte en ik ging ervan uit dat ik dit concept perfect begreep. Maar totdat ik in de praktijk met het ‘concurrency issue’ te maken kreeg, had ik geen idee van de ware angst die in die zin vervat zat.

“Waarom zou het aantal weergaven met 100 moeten stijgen, maar slechts met 98?” “Waarom stopt de website als ik Excel download?”

Mijn code was perfect toen ik hem alleen uitvoerde, maar het werd een puinhoop toen meerdere gebruikers tegelijk binnenkwamen. Ik dacht dat het opgelost zou worden door simpelweg het aantal ‘werkers’ te vergroten, maar ik wist niet dat naarmate het aantal medewerkers toeneemt, de kosten voor het beheer ervan (Context Switching) exponentieel stijgen.

Als je alleen werkt, is het vredig, maar als je met anderen samenwerkt, begint de oorlog.

Fabriek en werknemers in digitaal logistiek centrum

Laten we terugkeren naar het wereldbeeld van ons ‘digitale logistieke centrum’. Het uitvoeren van een programma op een computer is als het opzetten van een ‘fabriek’ in een distributiecentrum.

1. Proces: Zelfstandige werkplek

2. Onderwerp: Werknemers in de werkplaats

Threads hebben zowel een ‘gedeelde ruimte (Heap)’ als een ‘onafhankelijke ruimte (Stack)’.

[Codeverificatie] Tragedie van delen (gelijktijdigheidsprobleem)

‘Threads delen bronnen.’ Dit klinkt misschien als een voordeel in de interviewruimte, maar in de praktijk kan het de kiem zijn van een ‘ramp’.

Herinner je je de ‘Heap’ die we de vorige keer leerden? Discussies delen dit heapgebied. Dit betekent dat thread B de gegevens kan overschrijven waar thread A aan werkt.

Dit heet ‘Raceconditie’. Laten we het met code controleren.

public class RaceConditionTest {
    static int count = 0; // Gedeelde variabele opgeslagen in de Heap

    public static void main(String[] args) throws InterruptedException {
        // Twee werkers (threads) inhuren
        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(); // Werk starten!
        t2.start(); // Werk starten!
        
        t1.join(); // Wachten tot ze klaar zijn met werken
        t2.join(); // Wachten tot ze klaar zijn met werken
        
        System.out.println("Eindresultaat: " + count);
    }
}

Verwacht resultaat: aangezien twee mensen 10.000 keer hebben toegevoegd, zou het resultaat 20.000 moeten zijn.

Werkelijk resultaat: 15.482, 18.931… De waarde is elke keer anders als ik het uitvoer, en 20.000 wordt niet weergegeven.

Reden:

Dit is de identiteit van de bug die in de praktijk ‘soms op gegevens wordt gekauwd’. Dit is een tragedie die plaatsvond toen werknemers hetzelfde grootboek aanraakten zonder met elkaar te praten.

Als we deze situatie vergelijken met een database (DB), is dit hetzelfde als ‘een situatie waarin meerdere queries tegelijkertijd worden uitgevoerd zonder een transactie.’ Als tegelijkertijd het saldo van de bankrekening zonder slot wordt gewijzigd, gebeurt er een vreselijk ongeluk waarbij het geld verdampt. Net zoals we gegevens beschermen met ROLLBACK of COMMIT in de DB, is een vergrendelingsapparaat zoals Synchronized absoluut noodzakelijk op codeniveau.

Afweging in de praktijk: multi-proces versus multi-thread

Dus wanneer en wat moet je in de praktijk gebruiken?

1. Favoriete Chrome-browser: meerdere processen

Als in de oude Internet Explorer één tabblad stopte, werd de hele browser afgesloten (multi-threaded-methode). Chrome start elk tabblad echter als een ‘afzonderlijk proces (fabriek)’.

2. Keuze van de webserver (Spring, Node.js, etc.): Multi-threaded

De server moet duizenden verzoeken verwerken. Als je voor elk verzoek een proces (fabriek) bouwt, crasht de server. Het wordt dus verwerkt door meerdere threads (workers) in één proces te hebben.

Bouw je liever een veilig maar duur ‘fort’ of vlieg je liever met een snelle maar gevaarlijke ‘drone’?

Sluiting: zelfverbranding brengt verantwoordelijkheid met zich mee

Vandaag hebben we gekeken naar ‘processen en threads’, de manier waarop werknemers werken.

Nu weet je dat de term ‘concurrency issues’ niet zomaar een interviewterm is. Talrijke draadarbeiders bewegen zich voortdurend in en uit een gedeeld magazijn genaamd de Heap. Het is de vaardigheid van een back-end developer om orde te scheppen in deze chaos.

Maar wacht even, als er veel werknemers zijn, hoe beslis je dan wie eerst wiens werk moet doen? Hoe beheert een fabrieksmanager (OS) honderden werknemers? De volgende keer zullen we het hebben over de meest lastige taak van de fabrieksmanager: ‘Planning en contextwisseling.’

Plaats een reactie