Upload
galia
View
31
Download
0
Embed Size (px)
DESCRIPTION
Intro to Threads. CIS 4350 Rolf Lakaemper. Threads. Definitions first (Wikipedia): - PowerPoint PPT Presentation
Citation preview
INTRO TO THREADSCIS 4350Rolf Lakaemper
Definitions first (Wikipedia):“In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler… Multiple threads can exist within the same process and share resources such as memory”
Threads
Let’s start with a simple example.We want to write a program, that prints out a text every second.
Example
Bad Implementation public static void main(String[] args) { long time = System.currentTimeMillis(); int counter = 0; while (true) { long currentTime = System.currentTimeMillis(); if (currentTime - time > 1000) { time = currentTime; System.out.println("Hello “+ counter)); counter++;
} } }
Better yet Limited Implementation public static void main(String[] args) throws
InterruptedException { long time = System.currentTimeMillis(); int counter = 0; while (true) { Thread.sleep(1000); System.out.println("Hello " + counter); counter++; } }
This is a pause command. It indirectly points us to Threads, but
let’s not care right now.
ExampleThe limitation is, that the program (a) pauses for 1 second (b) requires a loop to be performed!Let’s extend the task, so these limitations
become clear:We want the user to be able to end the
program, by clicking ok in a dialog box. Unfortunately, when creating a dialog box, it waits for input (if we choose JOptionPane.showMessageDialog)).
Example This does not
work!Wait a second
Get input
Print TimeIt’s stuck right here!
End
Example What we need is a user input that does
not wait. JAVA of course provides these, but, for this example, let’s build our own version.
Our non-waiting box will explain why Threads are needed: our example problem is trying to handle two tasks: printing the time and waiting for input.
This problem can be modeled in a more elegant way than in a single loop:
Process Thread 2Thread 1
A better solution to our problem We have one process (our program), with two sub-processes (THREADS),
that run independently, yet communicate via a field (break flag)
Wait a second
Check break-flag
Print Time
End
Get User Input
Set break flagBrea
k flag
Back to the Definition“…a thread of execution is
the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler…
Multiple threads can exist within the same process and share resources such as memory”
Our two threads! The time-print-thread, and the input-
thread.
Our process: one program. The shared resource: the break
flag.
How to Code Threads in JAVA When you start your usual JAVA program,
it runs in a single thread, which starts the method main().
Additional Threads can be started by instantiating classes of Type “Runnable”, i.e. classes that implement the “Runnable” interface.
“Runnable” declares the method “run()” There’s a default implementation, the
“Thread” class, we can extend our own classes from.
The example revisited
Process Thread 2Thread 1
Break
flag
Main Processpublic class Main { private boolean breakFlag; class TimePrint extends Thread { }
class UserInput extends Thread { }
// ---------------------------- Main() { breakFlag = false; new TimePrint().start(); new UserInput().start(); }
public static void main(String[] args) throws InterruptedException { new Main(); }}
Remark:We are starting 3 threads here!1. “main”2. Thread13. Thread2“main” just dies after creating the other two.Thread1 dies when the break-condition is trueThread2 dies when ok was clicked.
The process terminates when all threads are dead, NOT when main terminates!
Thread 1class TimePrint extends Thread { public void run(){ int counter = 0; while (!breakFlag){ try { Thread.sleep(1000); } catch (InterruptedException ex) { } System.out.println("Hello "+counter); counter++; } } }
Shared resource!
Thread 2class UserInput extends Thread { public void run(){
JOptionPane.showMessageDialog(null, "Stop the Program");
breakFlag = true; } }
Shared resource!
Version 2: Implementation of the Runnable interface (example: Thread 2) class UserInput implements Runnable { public void run(){ JOptionPane.showMessageDialog(null, "Stop the
Program"); breakFlag = true; } }
… this version needs to be started using:
new Thread(new UserInput()).start();
AdvancedThreads can have multiple “states”We might talk about that later.…but we don’t necessarily have to.
Problems with Threads: Concurrency We share resources! If one thread writes to a resource while another one reads
from it, we might be in trouble! (the problem is that we only MIGHT be in trouble. One time
we are, another we are not, which makes debugging ugly!) The trouble: if the resources consist of multiple parts
(e.g. an array, consisting of many members). If thread1 re-writes a part while thread2 reads another part, thread2 might have different partial versions of the resource read after completion. Even worse: if thread1 deletes the resource, while thread2 reads it, the program might crash!
If resources consist of only a single part, everything is fine.
Concurrency
Array
Thread1Starts to
read
Array
Thread2writes
Array
Thread1Continues to
read
Array
Thread1Reading result:
time
“Single Part” resources are ok
Thread1Starts and
finishes reading
Thread2writes
Thread1Reading result:
time
Solution: make multi-part resources “Thread safe” - locking
A resource is thread safe when its access is “atomic”, i.e. a single virtual access cycle is needed.
This can be achieved by “locks”, which regulate access order.
Example:
Concurrency: Locking Example
Array
Method1Access to
Array
Method2Access to
Array
Version 1: no locking. Concurrency problem
Trouble!!!
Concurrency: Locking Example
Array
Method1Access to
ArrayMethod2Access to
Array
Version 1: locking. No concurrency problem
LockAccessUnlock
Locks A lock is an atomic resource It has two methods, which are virtual
one cycle methods: lock() and unlock() If a locked resource is attempted to be
locked again, it blocks the access (makes the Thread wait) until it gets unlocked.
“Locking” a data structure is to surround the multi-cycle access to it with a lock.
Java Example (example, see course website:
“ThreadExamples”)