2. Wikipedia
multithreading is the ability of a central processing unit (CPU) to
execute multiple processes or threads concurrently
3. Advantages
• Utilize more CPU power by reducing the impact of delaying
operations such as IO operations
• If a thread cannot use all the computing resources of the CPU
(because instructions depend on each other's result), running
another thread may prevent those resources from becoming idle
10. Race condition
Race conditions arise in software when an application depends on the
sequence or timing of processes or threads for it to operate properly
20. Priority Inversion
A problematic scenario in scheduling in which a high priority task is indirectly
preempted by a lower priority task effectively "inverting" the relative priorities of the two
tasks.
26. 64-bit values
(Java) single write to a non-volatile long or double value is treated as
two separate writes: one to each 32-bit half.
This can result in a situation where a thread sees the first 32 bits of a
64-bit value from one write, and the second 32 bits from another write.
32. int x = 0;
boolean finished = false;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
Take a moment to read the code… All modern CPUs have multiple
levels of CPU caches
33. Cache 1
Memory
int x = 0;
boolean finished = false;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 0;
finished = false;
Cache 2
x = 0;
finished = false;
34. Cache 1
Memory
int x = 0;
boolean finished = false;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 10;
finished = false;
Cache 2
x = 0;
finished = false;
35. Cache 1
Memory
int x = 10;
boolean finished = false;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 10;
finished = false;
Cache 2
x = 0;
finished = false;
X
36. Cache 1
Memory
int x = 10;
boolean finished = false;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 10;
finished = true;
Cache 2
x = 0;
finished = false;
37. Cache 1
Memory
int x = 10;
boolean finished = true;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 10;
finished = true;
Cache 2
x = 0;
finished = false;
finished
38. Cache 1
Memory
int x = 10;
boolean finished = true;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 10;
finished = true;
Cache 2
x = 0;
finished = false;
?
39. Cache 1
Memory
int x = 10;
boolean finished = true;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(x);
}
x = 10;
finished = true;
Cache 2
x = 0;
finished = true;
finished
40. Cache 1
Memory
int x = 10;
boolean finished = true;
void executeOnCpu1() {
x = 10;
finished = true;
}
void executeOnCpu2() {
while (!finished) {}
System.out.print(0);
}
x = 10;
finished = true;
Cache 2
x = 0;
finished = true;
41. Take a moment to read the code…
int orderOfEvaluation() {
return f1() + f2() + f3();
}
int orderOfEvaluationExplicit?() {
return (f1() + f2()) + f3();
}
42. int orderOfEvaluationExplicit() {
return f1() + f2() + f3();
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
43. int orderOfEvaluationExplicit() {
return 1 + f2() + f3();
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
44. int orderOfEvaluationExplicit() {
return 1 + 1 + f3();
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
45. int orderOfEvaluationExplicit() {
return 1 + 1 + 10;
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
The compiler can
evaluate operands in
any order (C++)
46. int orderOfEvaluationExplicit() {
return f1() + f2() + f3();
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
47. int orderOfEvaluationExplicit() {
return f1() + f2() + 10;
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
48. int orderOfEvaluationExplicit() {
return f1() + 10 + 10;
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}
49. int orderOfEvaluationExplicit() {
return 10 + 10 + 10;
}
class NoOrder {
int value = 1;
int f1() { return this.value; }
int f2() { return this.value; }
int f3() {
//...
this.value = 10;
//...
return this.value;
}
}