Concurrency Flashcards

1
Q

Stel, we hebben een thread:
~~~
Thread myThread = new Thread();
~~~
Wat moeten we uitvoeren om deze thread af te trappen?

A

myThread.start();
niet te verwarren met .run();

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Welke interface implementeert Tread?

A

Runnable

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Wat is de enige abstract method van de Runnable interface? En wat returnt het?

A

.run();
het returnt void.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Wat is de enige abstract method van de Callable interface? En wat returnt het?

A

.call()
het returnt een generic die in de interface is geimplementeerd. Dus, wanneer we Callable implementeren dienen we bijvoorbeeld te zeggen:
~~~
public class myClass implements Callable<Person>
~~~
En dan de call() method:
~~~
public Person call() {
return new Person("Harry", 22);
}
~~~</Person>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Wat kunnen we doen met Runnable en Callable?

A

Taken uitvoeren die in aparte threads kunnen worden uitgevoerd.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Werkt de volgende code? Waarom wel / niet?
~~~
Thread foo = new Thread(() -> {
Thread.sleep(1000);
System.out.println(“Foo Thread”);
});
~~~

A

Dit compileert niet omdat de .sleep() een checked exception gooit (InterruptedException). Moet dus in een try/catch:
~~~
Thread foo = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(“Foo Thread”);
});
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Stel, we hebben deze code:
~~~
static int count = 0;
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread t = new Thread(() -> incrementCount());
}
}

static void incrementCount() {
count++;
}
~~~
Wat is na het uitvoeren van de for loop de waarde van count?

A

0.
Let erop dat t niets doet tenzij je de thread ook daadwerkelijk start met t.start();

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Stel, we hebben deze code:
~~~
static int count = 0;
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread t = new Thread(() -> incrementCount());
t.start();
}
}

static void incrementCount() {
count++;
}
~~~
Dit levert geen betrouwbare resultaten op. Hoe zorg ik ervoor dat incrementCount maar door 1 thread tegelijk afgetrapt mag worden?

A

Door syncronized toe te voegen aan incrementCount:
~~~
syncronized static void incrementCount() {
count++;
}
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Wat doet een ReentrantLock?

A

De ReentrantLock implementeert de Lock interface en kan ervoor zorgen dat een bepaald stuk code maar 1 keer tegelijk aangetrapt wordt. Bijvoorbeeld:

public class Main {
    static Lock lock = new ReentrantLock();
		
		public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(() -> incrementCount());
            t.start();
        }
    }
		
    static void incrementCount() {
        lock.lock();
        // Dingen die maar in 1 thread tegelijk mogen gebeuren
        lock.unlock();
    }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

wat doet tryLock op een ReentrantLock? (zonder parameters)
wat geeft het terug?

A

tryLock probeert een lock te zetten. Als dit lukt geeft het een waarde van true terug (en lockt het vervolgens), en zo niet een waarde van false.
Op deze wijze kunnen we ervoor zorgen dat een stuk functionaliteit op 1 moment tegelijk mag draaien, en kunnen we een fallback maken voor wanneer dit stuk code al ‘in gebruik’ is.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

wat doet tryLock op een ReentrantLock? (met parameters)
wat geeft het terug?
welke parameter(s) moeten we opgeven?

A

tryLock probeert een lock te zetten. Als dit lukt geeft het een waarde van true terug (en lockt het vervolgens), en zo niet een waarde van false.
tryLock met parameters geeft een tijdslimiet aan; die aangeeft hoe lang er gewacht moet worden. Na deze limiet is het resultaat false.
De parameters zijn tijd en tijdsunit. Bijvoorbeeld:
lock.tryLock(2000, TimeUnit.MILLISECONDS)
Naast MILLISECONDS heb je ook:
* NANOSECONDS
* MICROSECONDS
* SECONDS
* MINUTES
* HOURS
* DAYS
Let erop dat beide parameters vereist zijn.

Net als Thread.sleep gooit de tryLock ook InterruptedException; dus deze moet in de method signature of een try/catch worden afgehandeld.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Hoe maak in een enkele thread aan waar een actie op uitgevoerd kan worden.

A

Twee opties:
1: Met een nieuwe thread:
~~~
Thread foo = new Thread(() -> doStuff());
foo.start();
~~~
2: Door een singleThreadExecutor aan te maken.
~~~
private static ExecutorService executor =
Executors.newSingleThreadExecutor();

public static void main(String[] args) {
executor.submit(() -> doStuff());
}
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Hoe voeren we taken uit binnen een x aantal thread pools?

A

met newFixedThreadPool. Bijvoorbeeld:
~~~
private static ExecutorService executor =
Executors.newFixedThreadPool(5);
~~~
Wanneer we dan deze code hebben:
~~~
for (int i = 0; i < 10; i++) {
executor.submit(() -> incrementCount());
}
~~~
Zal de executor van verschillende threads gebruik maken.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Wat doet de newCachedThreadPool? Welke interface implementeert het? Wat voor parameters neemt het op?

A

newCachedThreadPool implementeert ExecutorService en kan er als volgt uit zien:
~~~
private static ExecutorService executor = Executors.newCachedThreadPool();
~~~
Het neemt geen parameters op; en maakt een nieuwe thread aan wanneer de reeds aangemaakte threads bezet zijn en het systeem een nieuwe thread aan kan.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Wanneer kan een thread related object of method een InterruptedException gooien?

A

Wanneer er sprake is van een vertraging. Thread.sleep, tryLock, en .schedule in een scheduledThreadPool zijn hier voorbeelden van.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Wat doet de newScheduledThreadPool? Welke interface implementeert het? Wat voor methods kunnen we erop loslaten en welke parameters vragen deze methods?

A

newScheduledThreadPool implementeert ScheduledExecutorService en kan er als volgt uit zien:
~~~
private static ScheduledExecutorService executor = Executors.newCachedThreadPool(50);
~~~
We kunnen als volgt van de executor gebruik maken:
~~~
Future<Double> myNumber = executor.schedule(
() -> doSomething(),
1000,
TimeUnit.MILLISECONDS
)
~~~
Dit zegt dat doSomething over 1000 milliseconden moet worden uitgevoerd. Als doSomething een Double returnt, dan is het return type van myNumber dus Future<Double>.
met `myNumber.get(1500, TimeUnit.MILLISECONDS);` kan deze waarde worden opgehaald. (vergeet de InterruptedException niet af te vangen)</Double></Double>

17
Q

Collections als HashMap zijn niet geschikt voor gebruik in threads. Wat is de oplossing?

A

in plaats van HashMap kun je ConcurrentHashMap gebruiken; met dezelfde functionaliteit als HashMap, en thread support.

18
Q

Wat is de Queue variant die gebruikt kan worden voor Threads?

A

De interface BlockingQueue, en het object LinkedBlockingQueue.

19
Q

Stel, ik heb een ConcurrentSkipListSet:
~~~
Set<String> set = new ConcurrentSkipListSet<>();
set.add("Tim");
set.add("Pascal");
set.add("Elias");</String>

for(String s: set) {
System.out.println(s)
}
~~~
In welke volgorde worden de items geprint?

A

Elias, Pascal, Tim.

ConcurrentSkipListSet heeft een auto sort die in ieder geval probeert een basic sortering (nummers oplopend, of strings alfabetisch) toe te passen.

20
Q

Wat is een Map variant die gebruikt kan worden voor Threads?

A

ConcurrentSkipListMap. Is onderdeel van de Map interface.

21
Q

Stel, ik heb een ConcurrentSkipListMap:
~~~
Map<String, String> map = new ConcurrentSkipListMap<>();
set.put(“Guitar”, “Tim”);
set.put(“Bass”, “Pascal”);
set.add(“Piano”, “Elias”);

for(String s: map.keySet()) {
System.out.println(s)
}
~~~
In welke volgorde worden de items geprint?

A

Bass, Piano, Guitar.

ConcurrentSkipListMap heeft een auto sort die in ieder geval probeert een basic sortering (nummers oplopend, of strings alfabetisch) toe te passen. Dit betreft de keys, niet de values.

22
Q

Wat is een List variant die gebruikt kan worden voor Threads?

A

CopyOnWriteArrayList. Is onderdeel van de List interface.

23
Q

Wat is een Set variant die gebruikt kan worden voor Threads?

A

CopyOnWriteArraySet. Is onderdeel van de Set interface.

24
Q

Wat is het voornaamste verschil tussen CopyOnWriteArrayList en CopyOnWriteArraySet?

A

De list kan duplicates bevatten. Wanneer we een item aan de set toevoegen die al bestaat gebeurt er simpelweg niets.

25
Q

Wat voor Atomic variables zijn er?

A
  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
26
Q

Noem drie methods die bij een Atomic variable aangeroepen kunnen worden

A

Bijvoorbeeld:
* get() haalt een waarde op
* set() set een waarde
* compareAndSet() set een waarde als de waarde van de variable er niet mee overeen komt
* weakCompareAndSet()
* lazySet()

27
Q

Wat is een deadlock?

A

Een punt waarop de applicatie oneindig wacht op input of een reactie uit een andere method.
Voorbeeld is wanneer een Thread een bepaalde resource lockt, en een andere thread deze resource nodig heeft.

Analogie: Een misdadiger heeft gijzelaars en wil zijn som geld voordat hij de gijzelaars vrij laat. De politie buiten heeft de som geld maar geeft dit pas als de gijzelaars zijn vrijgelaten. Beide partijen wachten zo eindeloos op elkaar.

28
Q

Wat is een livelock?

A

Verschillende Threads die op hetzelfde moment resources willen vrijgeven of bezetten en hierin elkaar in de weg zitten.

Analogie: Je staat tegenover iemand op straat. Jullie willen langs elkaar. Jij doet een stap een kant op; en de ander zet een stap dezelfde kant op waardoor jullie weer tegenover elkaar staan en niet langs elkaar kunnen lopen.

29
Q

Wat doet .setDaemon(true) op een Thread?

A

Geeft aan dat de applicatie niet wacht op de nog lopende threads in de applicatie. Dus bijvoorbeeld:

public class Zoo {
    public static void pause() {
        try {
            Thread.sleep(10_000);
        } catch (InterruptedException e) {}
        System.out.println("Thread finished!");
    }

    public static void main(String[] unused) {
        var job = new Thread(() -> pause());
        job.start();
        System.out.println("Main method finished!");
    }
}

Bovenstaande code laat de main method Main method finished! printen en dan 10 sec. wachten. Maar zetten we job.setDaemon(true), dan negeert dit de Thread lifecycle en sluit het programma voordat Thread Finished wordt geprint.

30
Q

Hoe zorgen we ervoor dat een thread executor wordt afgesloten? En hoe gaat het om met nog draaiende taken?

A

met .shutdown();
Alle tasks die op dat moment draaien worden afgerond, en daarna wordt de executor gesloten. Nieuwe taken worden geweigerd.

31
Q

Hoe zorgen we ervoor dat een thread executor wordt afgesloten, en alle nog draaiende taken worden geannuleerd (waar mogelijk).

A

.shutdownNow()

32
Q

Wat is in de ExecutorService interface het verschil tussen .submit en .execute?

A

.execute voert een taak uit en returnt verder niets. Met .submit kunnen we de state van deze taak bijhouden; dit returnt een Future object.

33
Q

Hoe wachten we een bepaalde tijd op het afronden van een ExecutorService

A

Met awaitTermination.
Bijvoorbeeld:
~~~
ExecutorService service =
Executors.newSingleThreadExecutor();
// Voer taken in de thread uit
service.awaitTermination(1, TimeUnit.MINUTES);
~~~
Hier wacht het een minuut voordat het verdergaat met de volgende regel.

34
Q

Hoe testen we of een newSingleThreadExecutor is afgesloten?

A

service.isTerminated(). Dit returnt een boolean

35
Q
A