Overview of Java Threads
(Part 1)
Douglas C. [email protected]
www.dre.vanderbilt.edu/~schmidt
Institute for Software
Integrated Systems
Vanderbilt University
Nashville, Tennessee, USA
2
• Understand how Java threads support concurrency
Learning Objectives in this Part of the Lesson
Process A Process B Process C
Concurrent apps use threads to simultaneously run multiple computations that potentially interact with each other
3
• Understand how Java threads support concurrency
• Learn how our case study app works
Learning Objectives in this Part of the Lesson
See github.com/douglascraigschmidt/POSA/tree/master/ex/M3/GCD/Concurrent
4
• Understand how Java threads support concurrency
• Learn how our case study app works
• Know alternative ways of giving code to a thread
Learning Objectives in this Part of the Lesson
Thread
Thread(Runnable)
start()
…
Runnable
run()
GCDRunnable
run()
…
Thread
run()
start()
…
GCDThread
run()
…
5
• Understand how Java threads support concurrency
• Learn how our case study app works
• Know alternative ways of giving code to a thread
• Learn how to pass parameters to a Java thread
Learning Objectives in this Part of the Lesson
6
Introduction to Java Threads
7
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
Process B
A Java thread is a unit of computation that runs in the context of a process
See en.wikipedia.org/wiki/Thread_(computing)
8
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
Process B
A process is a unit of resource allocation &
protection
See en.wikipedia.org/wiki/Process_(computing)
9
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
Process A Process B Process C
Java enables multiple threads to run in multiple processes
See docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html
10
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
Process A Process B Process C
Java threads running in the same process can communicate with each other via shared objects or message passing
See www.javatpoint.com/inter-thread-communication-example & web.mit.edu/6.005/www/fa14/classes/20-queues-locks/message-passing
11
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
Process A Process B Process C
Java threads running in different processes can communicate with each other via shared memory or inter-process communication (IPC) mechanisms
We’ll focus later on Android-centric forms of shared memory & IPC
Shared
MemoryIPC
12
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
See en.wikipedia.org/wiki/Thread_(computing)#Processes.2C_kernel_threads.2C_user_threads.2C_and_fibers
Process A Process B Process C
Each Java thread leverages unique “state” from the underlying operating system thread, e.g., a runtime
stack, an instruction counter, & other registers
13
• Threads are the most basic way of obtaining concurrency in Java
Introduction to Java Threads
Process A Process B Process C
Java dynamic & static objects can be shared across Java threads (i.e., this “state” is common)
See en.wikipedia.org/wiki/Thread_(computing)#Processes.2C_kernel_threads.2C_user_threads.2C_and_fibers
14
The GCD Concurrent App Case Study
15
• This app shows various methods in Java’s Thread class & alternative ways of giving code to a Java thread
The GCD Concurrent App Case Study
See github.com/douglascraigschmidt/POSA/tree/master/ex/M3/GCD/Concurrent
16
• This app shows various methods in Java’s Thread class & alternative ways of giving code to a Java thread, e.g.
• By implementing the Runnable interface
The GCD Concurrent App Case Study
See github.com/douglascraigschmidt/POSA/tree/master/ex/M3/GCD/Concurrent/app/src/main/java/vandy/mooc/gcd/activities/GCDRunnable.java
Thread
Thread(Runnable)
start()
…
Runnable
run()
GCDRunnable
run()
…
17
• This app shows various methods in Java’s Thread class & alternative ways of giving code to a Java thread, e.g.
• By implementing the Runnable interface
• By inheriting from the Thread class
The GCD Concurrent App Case Study
Thread
run()
start()
…
GCDThread
run()
…
See github.com/douglascraigschmidt/POSA/tree/master/ex/M3/GCD/Concurrent/app/src/main/java/vandy/mooc/gcd/activities/GCDThread.java
18
Ways of Giving Code to Java Threads
19
• Java threads must be given code to run
Ways of Giving Code to Java Threads
20
• Java threads must be given code to run
Ways of Giving Code to Java Threads
Thread t = new Thread();
t.start();
Do not use the “no argument” Thread constructor directly!!!
See stackoverflow.com/questions/7572527/why-would-anyone-ever-use-the-java-thread-no-argument-constructor
21
• Java threads must be given code to run
Ways of Giving Code to Java Threads
There are alternative programming models for giving code to Java threads
22See docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
• Java threads must be given code to run, e.g.
1. Extend the Thread class
Thread
run()
start()
…
GCDThread
run()
…
Ways of Giving Code to Java Threads
public class GCDThread
extends Thread {
public void run() {
// code to run goes here
}
}
23
• Java threads must be given code to run, e.g.
1. Extend the Thread class
Thread
run()
start()
…
GCDThread
run()
…
Ways of Giving Code to Java Threads
public class GCDThread
extends Thread {
public void run() {
// code to run goes here
}
}
Override the run() hook method in the subclass & define the thread’s computations
See wiki.c2.com/?HookMethod
24
• Java threads must be given code to run, e.g.
1. Extend the Thread class
Thread
run()
start()
…
GCDThread
run()
…
Ways of Giving Code to Java Threads
public class GCDThread
extends Thread {
public void run() {
// code to run goes here
}
}
Thread gCDThread =
new GCDThread();
gCDThread.start();
Create & start a thread using a named subclass of Thread
25
• Java threads must be given code to run, e.g.
1. Extend the Thread class
Thread
run()
start()
…
GCDThread
run()
…
Ways of Giving Code to Java Threads
public class GCDThread
extends Thread {
public void run() {
// code to run goes here
}
}
new GCDThread().start();
You can also write a one-liner to create & start an anonymous thread
26
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
Ways of Giving Code to Java Threads
Runnable
run()
See docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
27
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
Ways of Giving Code to Java Threads
Runnable
run()
GCDRunnable
run()
…
See docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html
Implement the run() hook method of an interface to define the thread’s computations
28
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
Ways of Giving Code to Java Threads
Runnable
run()
GCDRunnable
run()
…
29
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
Ways of Giving Code to Java Threads
Runnable
run()
GCDRunnable
run()
…
public class GCDRunnable
implements Runnable {
public void run() {
// code to run goes here
}
}
Runnable gCDRunnable =
new GCDRunnable();
Create an instance of a named class as the runnable
30
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
public class GCDRunnable
implements Runnable {
public void run() {
// code to run goes here
}
}
Runnable gCDRunnable =
new GCDRunnable();
new Thread(gCDRunnable).start();
Ways of Giving Code to Java Threads
Thread
Thread(Runnable)
start()
…
Runnable
run()
GCDRunnable
run()
…
Pass that runnable to a new thread object & start it
31
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
new Thread(new Runnable() {
public void run(){
// code to run goes here
}
}).start();
Ways of Giving Code to Java Threads
Runnable
run()
<<anonymous>>
run()
…
Thread
Thread(Runnable)
start()
…
Create & start a thread using an anonymous inner
class as the runnable
32
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
This anonymous inner class idiom is used extensively in older Java & Android code
Ways of Giving Code to Java Threads
Runnable
run()
<<anonymous>>
run()
…
Thread
Thread(Runnable)
start()
…
new Thread(new Runnable() {
public void run(){
// code to run goes here
}
}).start();
33
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
3. Use Java 8 lambda expressions (variant of #2)
new Thread(() -> {
// code to run goes here
}).start();
Ways of Giving Code to Java Threads
Runnable
run()
<<anonymous>>
run()
…
Thread
Thread(Runnable)
start()
…
See www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764
A lambda expression is an unnamed block of code (with optional parameters) that can be passed around & executed later
34
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
3. Use Java 8 lambda expressions (variant of #2)
new Thread(() -> {
// code to run goes here
}).start();
Ways of Giving Code to Java Threads
Runnable
run()
<<anonymous>>
run()
…
Thread
Thread(Runnable)
start()
…
This approach is unwieldy if the code to run is long, complex, or needs to be used multiple times!
35
• Java threads must be given code to run, e.g.
1. Extend the Thread class
2. Implement the Runnable interface
3. Use Java 8 lambda expressions (variant of #2)
Ways of Giving Code to Java Threads
Runnable
run()
<<anonymous>>
run()
…
Thread
Thread(Runnable)
start()
…
You can therefore store the runnable in a variable & pass it to the Thread constructor
Runnable r = () -> {
// code to run goes here
};
new Thread(r).start();
36
Passing Parameters to a Java Thread
37
• The run() methods defined in Java Thread & Runnable take no parameters
Passing Parameters to a Java Thread
This raises the question of how to pass parameters to a Java thread!
38
• Parameters passed to run() can be supplied via one of two other means
Passing Parameters to a Java Thread
39
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
Passing Parameters to a Java Thread
public class GCDRunnable extends Random implements Runnable {
See github.com/douglascraigschmidt/POSA/tree/master/ex/M3/GCD/Concurrent/app/src/main/java/vandy/mooc/gcd/activities/GCDRunnable.java
40
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
Passing Parameters to a Java Thread
public class GCDRunnable extends Random implements Runnable {
private final MainActivity mActivity;
...
Define field(s) to store parameters passed to a runnable or thread object
41
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
Passing Parameters to a Java Thread
public class GCDRunnable extends Random implements Runnable {
private final MainActivity mActivity;
public GCDRunnable(MainActivity mainActivity)
{ mActivity = mainActivity; }
...
Add the parameter(s) to the constructor signature & store them in the field(s)
42
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
Passing Parameters to a Java Thread
public class GCDRunnable extends Random implements Runnable {
private final MainActivity mActivity;
public GCDRunnable(MainActivity mainActivity)
{ mActivity = mainActivity; }
public void run() {
final String threadString =
" with thread id " + Thread.currentThread();
mActivity.println("Entering run()" + threadString);
...
Use the field(s) within the thread’s run() hook method to customize its behavior
43
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
Passing Parameters to a Java Thread
public class GCDRunnable extends Random implements Runnable {
private final MainActivity mActivity;
public GCDRunnable(MainActivity mainActivity)
{ mActivity = mainActivity; }
public void run() {
final String threadString =
" with thread id " + Thread.currentThread();
mActivity.println("Entering run()" + threadString);
...
public class MainActivity ... { ...
public void runRunnable(View v) { ...
new Thread(new GDCRunnable(this));
...
Pass the parameter(s) when the runnable or
thread is created
44
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
• As parameters to “setter” methods
Passing Parameters to a Java Thread
public class GCDThread extends Thread {
See github.com/douglascraigschmidt/POSA/tree/master/ex/M3/GCD/Concurrent/app/src/main/java/vandy/mooc/gcd/activities/GCDThread.java
45
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
• As parameters to “setter” methods
Passing Parameters to a Java Thread
public class GCDThread extends Thread {
private MainActivity mActivity; private Random mRandom;
...
Define field(s) to store parameters passed to a runnable or thread object
46
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
• As parameters to “setter” methods
Passing Parameters to a Java Thread
public class GCDThread extends Thread {
private MainActivity mActivity; private Random mRandom;
public GCDThread setActivity(MainActivity activity)
{ mActivity = activity; return this; }
public GCDThread setRandom(Random random)
{ mRandom = random; return this; }
...
Define setter methods that update field(s)
47
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
• As parameters to “setter” methods
Passing Parameters to a Java Thread
public class GCDThread extends Thread {
private MainActivity mActivity; private Random mRandom;
public GCDThread setActivity(MainActivity activity)
{ mActivity = activity; return this; }
public GCDThread setRandom(Random random)
{ mRandom = random; return this; }
...
See en.wikipedia.org/wiki/Fluent_interface
Note use of “fluent interfaces”
48
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
• As parameters to “setter” methods
Passing Parameters to a Java Thread
public class GCDThread extends Thread {
private MainActivity mActivity; private Random mRandom;
public GCDThread setActivity(MainActivity activity)
{ mActivity = activity; return this; }
public GCDThread setRandom(Random random)
{ mRandom = random; return this; }
...
public void run() { ...
mActivity.println("Entering run()" + threadString);
...
int number1 = mRandom.nextInt();
int number2 = mRandom.nextInt(); ...
Use the fields within the thread’s run() hook method to customize its behavior
49
• Parameters passed to run() can be supplied via one of two other means, e.g.
• As parameters to a class constructor
• As parameters to “setter” methods
Passing Parameters to a Java Thread
public class GCDThread extends Thread {
...
public class MainActivity ... { ...
public void runThread(View v) { ...
Thread thread =
new GCDThread()
.setActivity(this)
.setRandom(new Random());
...
Use the fluent interface to pass parameter(s) when the runnable or thread is created
50
End of Overview of Java Threads (Part 1)