Multi-Threading

lightnewsSoftware and s/w Development

Nov 18, 2013 (3 years and 9 months ago)

93 views

Multi-Threading
… in user interfaces
Long Tasks
!

What should you do when a task will take signi

cant time?
-

Fetching a large image or long list over a (slow) internet
connection
-

Factoring a large number
-

Reading a large

le
-

Searching a directory structure
-

Performing an image processing operation
-

etc.
CS 349 - Multithreading
2
Demo1.java
(what not to do)
Practice Exercise
CS 349 - Multithreading
3
[ 8 marks ] You wish to implement an interactive application to
calculate a list of prime numbers (ranging from min to max). Your
interface must have a way to “start” and “stop” the prime number
calculation and a text box to display the list of prime numbers.
a)

[ 2 ] What could you do to help people form a mental model that the
application is still processing and not “frozen”? Give the design
principle that you are using.
b)

[ 6 ] How would you design your application using the classic
“Smalltalk” MVC architecture discussed in class?




Demo1, Demo2, and Demo3 MVC Architecture
CS 349 - Multithreading
4
Demo1.java (what not to do)
CS 349 - Multithreading
5
protected
(
void
(
registerControllers
()({(
(
//(Handle(presses(of(the(start(button
(
(
this
.
startStopButton
.addActionListener
(
new
(
(
(
(
ActionListener
()({(
(
(
((((
public
(
void
(
actionPerformed
(
ActionEvent
(e)({(
(
(
(
(((((((
model
.calculatePrimes
();(
(
(
((((}(
(
((((});(
}(
(
Find primes in
[1, 250000]
Takes ~10 seconds
to complete
What’s wrong?
CS 349 - Multithreading
6
actionPerformed

model.calculatePrimes
()
Goal for Long Tasks
!

Maintain a highly interactive application
(even if it takes a bit longer to complete the task)
-

keep UI responsive
-

provide progress feedback
-

allow long task to be paused or canceled
CS 349 - Multithreading
7
Cancel!
is it
running?
Two Strategies for Long Tasks
!

Strategy A: Run in UI Thread (by breaking into subtasks)

-

Periodically execute each subtask on the UI thread (between
handling regular events)
!

Strategy B: Run in separate thread (and communicate
with UI thread)
-

Create a “worker thread” and thread-safe API
!

For both strategies, provide API for UI to control task and for
task to provide feedback to UI:
void(run()(
void(cancel()(
boolean
(
isRunning
()(
boolean
(
isDone
()(
boolean
(
wasCancelled
()(
int
(progress()(
CS 349 - Multithreading
8
Strategy A: Run in UI Thread (Demo2.java)
!

Task object keeps track of current task progress
!

Subtasks periodically called on Swing event thread
-

See
SwingUtilities.invokeLater
() for way to execute on Swing
thread
-

Alternatively, see
javax.swing.Timer

(there is also
java.util.Timer
; use the Swing version)
!

Every time object told to “run” checks current progress,
executes subtask, updates progress, cancels if asked, …
CS 349 - Multithreading
9
CS 349 - Multithreading
10
class
(Model2(
extends
(
AbstractModel
({(
(
private
(
boolean
(
cancelled
(=(
false
;(
(
private
(
boolean
(
running
(=(
false
;(
(
private
(
int
(
current
(=(0;(((
(
//(progress(so(far
(((((((
(
(
public
(Model2(
int
(min,(
int
(max)({((
super
(min,(max);((}(
(
(
public
(
void
(
calculatePrimes
()({(
(
(
this
.
running
(=(
true
;(
(
(
SwingUtilities.invokeLater
(
new
(Runnable()({(
(
(
(
public
(
void
(run()({(
(
(
(
(
//(calculate(primes(for(100(
ms
((
(
(
(
(
calculateSomePrimes
(100);((
(
(
(
(
if
((!
cancelled
(&&(
current
(<=(
max
)({(
(
(
(
(
(
calculatePrimes
();(
(
(
(
(
}(
(
(
(
}(
(
(
});(
(
}(
CS 349 - Multithreading
11
private
(
void
(
calculateSomePrimes
(long(duration)({(
(
long
(start(=(
System.currentTimeMillis
();(
(
while
((
true
)({(
(
(
if
((
this
.
current
(>(
this
.
max
)({(
(
(
(
this
.
running
(=(
false
;(
(
(
(
updateAllViews
();(
(
(
(
return
;(
(
(
}(
else
(
if
((
System.currentTimeMillis
()(W(start(>=((((((
(((((((((((((((((((((((((((((((((((((((((((((duration)({(
(
(
(
updateAllViews
();(
(
(
(
return
;(
(
(
(
}(
else
(
if
((
isPrime
(
this
.
current
))({(
(
(
(
this
.addPrime
(
current
);(
(
(
}(
(
(
current
(+=(1;(
(
}(
}(
Strategy A
!

Advantages:
-

Can more naturally handle “pausing” (stopping/restarting) task
because it maintains information on progress of overall task
-

Can be run in Swing event thread or separate thread
-

Useful in single-threaded platforms (e.g., iPhone,
iPad
, etc.)
!

Disadvantages:
-

Tricky to predict length of time for subtasks
-

Not all tasks can easily break down into subtasks
(e.g., Blocking I/O)
CS 349 - Multithreading
12

These are some big disadvantages,
it’s better to use threads (Strategy B) when possible.

Strategy B: Run in separate thread (Demo3.java)
!

Long method runs in a separate thread
-

Typically implemented via Runnable object
!

Method regularly checks if task should be cancelled and
reports back to UI about progress (by updating views)
CS 349 - Multithreading
13
class
(Model3(
extends
(
AbstractModel
({(
(
...(
(
public
(
void
(
calculatePrimes
()({(
(
(
new
(Thread()({(
(
(
(
(
public
(
void
(run()({(
(
(
(
(
...((
(
(
(
}(
(
(
(
(
private(void
(
updateUI
()({(
(
(
(
(
...(
(
(
(
}(
(
(
(
}.start();
(
CS 349 - Multithreading
15
(
(
(
public
(
void
(run()({(
(
(
(
(
running
(=(
true
;(
(
(
(
(
long
(start(=(
System.currentTimeMillis
();(
(
(
(
(
while
((
true
)({(
(
(
(
(
((
if
((
cancelled
(||(
current
(>(
max
)({(
(
(
(
(
(
(
running
(=(
false
;(
(
(
(
(
(
(
updateUI
();(
(
(
(
(
(
(
return
;(
(
(
(
(
(((}(
else
(
if
((
isPrime
(
current
))({(
(
(
(
(
(
(
addPrime
(
current
);(
(
(
(
(
(((}(
(
(
(
(
(((
current
(+=(1;
(
(
(
(
(
(
(((
if
((
System.currentTimeMillis
()(W(start(>=(100)({(
(
(
(
(
(
(
updateUI
();(
(
(
(
(
(
(
start(=(
System.currentTimeMillis
();(
(
(
(
(
(
}(
(
(
(
(
}(
(
(
(
}(
(
(
(
(
CS 349 - Multithreading
16
private
(
void
(
updateUI
()({(
(
SwingUtilities.invokeLater
(
new
(Runnable()({(
(
(
public
(
void
(run()({(
(
(
(
updateAllViews
();(
(
(
}(
(
});
(
(
(
(
}(
Strategy B
!

Advantages:
-

Conceptually, the easiest to implement
-

Takes advantage of multi-core architectures
!

Disadvantages:
-

Extra code required to be able to pause/restart method
-

All the usual Thread baggage
Race conditions
Deadlocks
Etc.
CS 349 - Multithreading
17
Using a Separate Thread
!

Remember that Swing is not thread safe!
!

Don’t call Swing methods or access Swing components from
outside the Event Dispatch thread
!

From task thread, use
invokeLater
to schedule code to run
in the Event Dispatch thread
!

Use synchronized keyword to protect critical sections
CS 349 - Multithreading
18
Threading in Swing
!

Three types of threads:
1.

Initial Thread
2.

Event Dispatch Thread (EDT) (or “UI Thread”)
3.

Worker Threads (or “Background Threads”)
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

CS 349 - Multithreading
19
(
public
(
static
(
void
(main(String[](
args
)({(
(
(
SwingUtilities.
invokeLater
(
new
-Runnable()-{-
(
(
(
public
(
void
(run()({(
(
(
(
(
new
(Demo4();(
(
(
(
}(
(
(
});
(
(
(
}
(
Scheduling Code to Run on UI Thread
!

invokeAndWait
()
!

invokeLater
()
!

Runnable() (
vs
Thread())
CS 349 - Multithreading
20
private
(
void
(
updateUI
()({(
(
SwingUtilities.invokeLater
(
new
(Runnable()({(
(
(
public
(
void
(run()({(
(
(
(
...(do(something(on(UI(thread(...(
(
(
}(
(
});
(
(
(
(
}(
synchronized
keyword
!

Java’s strategy for handling concurrency is to use the
Monitor abstraction
-

Conceptually higher level than semaphores and
mutexs

-

Overall goal is the same: provide mutually exclusive access to
critical sections
!

Methods marked with the “synchronized” keyword can only
be access by one thread a time.
-

Synchronizing both run() and cancel() methods means cancel()
can’t execute until after run() has

nished
CS 349 - Multithreading
21
“synchronized” keyword
CS 349 - Multithreading
22
public

class

ThreadSafeCounter
{


private

int

c
= 0;



public

synchronized

void
increment() {


this
.
c
++;

}



public

synchronized

void
decrement() {


this
.
c
--;

}



public

synchronized

int
value() {


return

this
.
c
;

}

}

SwingWorker

!

As of Java SE 6, there’s a standard way to create worker
threads:
SwingWorker

!

Good introductory tutorials:
-

http://www.javacreed.com/swing-worker-example/

-

http://www.javaadvent.com/2012/12/multi-threading-in-java-
swing-with.html

!

Android has something similar,
AsyncTask

-

http://developer.android.com/reference/android/os/
AsyncTask.html

CS 349 - Multithreading
23
Long Tasks and MVC
!

MVC strives to have a complete separation between model
and view
!

What do you see happening as we break task up?
CS 349 - Multithreading
24
Long Tasks and MVC
!

Long tasks start to break clean separation of MVC
!

Model’s methods need to be designed to allow user to stop
them, to maintain interactivity
-

Needed to service event queue
-

Needed to allow user to stop method
!

May need methods to inquire about length of task
completion
-

Not part of “model” – part of interaction
!

Usability concerns are thus directly in

uencing design of
model to accommodate user interaction
CS 349 - Multithreading
25