Concurrency
> Click or hit Control-Enter to run Example.main above
Originally: Single-Core Processors

But Then How Could You Use Multiple Applications At Once?
The Illusion
But Look Closer…
And Even Closer…
The Illusion of Parallelism
All processors create the illusion of parallelism by rapidly switching between multiple programs.
Human Perceptual Limitations
Why does this work? Because you are slow.
Assuming a 1 GHz processor:
-
15 ms "rule of thumb": 15,000,000 clock cycles!
-
40 ms based on 25 frames-per-second for "smooth" video: 40,000,000 clock cycles!
-
100 ms was the rule for old telephone systems, the delay point after which human conversation patterns start to break down: 100,000,000 clock cycles!
Today: Multicore Everywhere

Today’s Reality: Both Real and Illusory Parallelism
Today even your phone has multiple cores. So we have both:
-
Real parallelism: your phone is actually doing multiple things at once
-
Illusory parallelism: each core is still rapidly switching between programs to create the illusion of more parallelism.
Single-Threaded
public class Example {
private static void process() {
for (int i = 0; i < 20000000L; i++);
}
public static void main(final String[] unused) {
long startTime = System.nanoTime();
for (int i = 0; i < 4; i++) {
process();
}
System.out.println((System.nanoTime() - startTime) / 1000000.);
}
}
So far all of the code we’ve written this semester only does one thing at a time.
Sometimes we call this single-threaded, for reasons that will make sense shortly.
> Click or hit Control-Enter to run Example.main above
But We Have Multiple Cores!
Parallelism In Java
Java allows us to create a separate thread of execution using the Thread
class.
-
Each
Thread
executes separately, and threads may run in parallel on different cores if possible. -
Each
Thread
can access the same program variables as other threads.
But What Is a Thread
To Do?
Runnable
s
public class Example implements Runnable {
public void run() {
System.out.println("Hello!");
}
public static void main(final String[] unused) {
Thread t = new Thread(new Example());
t.start();
}
}
When we create a Thread
we need to give it something to do—a function as
an entry point. (Remember main
?)
We do this by having our class implement Runnable
and provide a public void
run()
method.
> Click or hit Control-Enter to run Example.main above
> Click or hit Control-Enter to run Example.main above
Controlling Threads
Java has multiple methods for controlling and communicating with Thread
objects:
-
thread.start()
: begin executing aThread
-
thread.join()
: wait for aThread
to complete -
thread.interrupt()
: interrupt aThread
, causing anInterruptedException
to be thrown
> Click or hit Control-Enter to run Example.main above
> Click or hit Control-Enter to run Example.main above
> Click or hit Control-Enter to run Example.main above
Concurrency v. Parallelism
You hear the terms parallelism and concurrency used together a lot, but each has a specific meaning:
-
Parallelism: multiple things are happening at the same time
-
Concurrency: multiple parts of your program can make progress at the same time
-
Watch this talk by Googler Rob Pike if you want to clear up this distinction
Why Concurrency Is Important
Parallelism is important if your program spends a lot of time computing—but most programs don’t.
They spend a lot of time waiting for other things to happen:
-
Waiting for the user to enter some input
-
Waiting for a read from the disk to complete
-
Waiting for some data from the network
-
Waiting for your web API call to complete
If your program is concurrent, something useful can happen even while you’re waiting for something else.
Android Aside
On Android there is a single user interface (UI) thread responsible for handling input like clicks.
-
If that thread get stuck waiting, the entire UI becomes unresponsive.
-
Which is why you need to do slow things using a background task—or, in the case of Volley, using its queue.
-
This way the UI thread stays responsive even while slow operations like network requests are being completed.
> Click or hit Control-Enter to run Example.main above
> Click or hit Control-Enter to run Example.main above
But Concurrency Can Create Problems…
> Click or hit Control-Enter to run Example.main above
Race Condition
A race condition or race hazard is the behavior of an electronics, software, or other system where the output is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when events do not happen in the order the programmer intended.
Account Example: No Locking
Thread 1 | Thread 2 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Locks
One programming technique to avoid race conditions is to use a lock:
-
Once one
Thread
grabs a lock no other threads can use the lock. -
We then do our operation on the shared variable or resource.
-
And then drop the lock so that other threads can acquire it.
Account Example: Locking
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Java synchronized
Keyword
// Only one `Thread` can run this method at once on each object
public synchronized void withdraw() {
int currentAccountBalance = accountBalance;
System.out.println(currentAccountBalance);
currentAccountBalance -= 10;
if (currentAccountBalance < 0) {
// throw Exception
}
accountBalance = currentAccountBalance;
}
Java has a special keyword called synchronized
that allows us to easily add a
lock to any existing method.
Java synchronized
Keyword
// Only one `Thread` can run this method at once on the entire class
public static synchronized void withdraw() {
int currentAccountBalance = accountBalance;
System.out.println(currentAccountBalance);
currentAccountBalance -= 10;
if (currentAccountBalance < 0) {
// throw Exception
}
accountBalance = currentAccountBalance;
}
> Click or hit Control-Enter to run Example.main above
However, Locking Degrades Concurrency
Concurrency encourages a Thread
free for all, while locking makes them get in
line.
> Click or hit Control-Enter to run Example.main above
Questions About Concurrency or Parallelism?
Final Project Video
Before you attend this week’s lab you need to upload your final project video to YouTube and submit the link using this form.
-
We’ll be showing these videos in class…
-
…and at Thursday’s Final Project Fair.
-
Format is up to you, but you should definitely demo and discuss your final project. Both partners should be involved somehow.
Final Project Fair
A reminder that our inaugural CS 125 Final Project Fair is this Thursday (5/3/2018) from 4–6PM in Siebel. 1% extra credit for participating.
-
Each lab section will choose two most impressive projects: one from a group of beginners, and a second in an open category.
-
Judging is from 4–5:15PM, meaning that you should be set up and ready to go at 4PM.
-
There will be (good) food.
-
There will be awards at 5:30PM in Siebel 1404.
Wednesday: Review and ICES
Wednesday we’ll discuss the final exam and I’ll take questions.
And, we’ll do the ICES forms:
-
If you get to 70% I’ll release one of the short programming problems from the exam
-
If you get to 80% I’ll release another programming problem from the exam
-
If you get to 90% I’ll release a hard programming problem from the exam
-
Note that the TAs will be supervising the ICES forms so that I can trust the count. And the 8AM and 10AM classes are in this together.
Tonight: ICES for EMP
Tonight is the last EMP session. We’ll also do the ICES forms for EMP.
-
If you’ve come at all this semester you’ve probably realized that Liia and her team are super helpful.
-
Please show up tonight for some review and to leave her constructive ICES feedback.
Announcements
-
MP7 (the final project) is out. Start wrapping up—demos are this week and the fair is Thursday.
-
The anonymous feedback form remains available on the course website. Use it to give us feedback!
-
My office hours continue today at 11AM in the lounge outside of Siebel 0226.