Date post: | 14-Dec-2015 |
Category: |
Documents |
Upload: | sage-gidney |
View: | 250 times |
Download: | 6 times |
Concurrency (p2)Concurrency (p2)
synchronized (this) {
doLecture(part2);
}
synchronized (this) {
doLecture(part2);
}
Quick ReviewQuick Review
Threads can up performance Java’s 2 parts for thread safety
AtomicityVisibility
Java’s Primitivesvolatilesynchronized
Library SupportAtomic variablesConcurrent collectionsCommon synchronizers
(BlockingQueue)
Threads can up performance Java’s 2 parts for thread safety
AtomicityVisibility
Java’s Primitivesvolatilesynchronized
Library SupportAtomic variablesConcurrent collectionsCommon synchronizers
(BlockingQueue)
OutlineOutline
Executor FrameworkShutdown and cancellationSwing and ConcurrencyCustom Synchronizers
Executor FrameworkShutdown and cancellationSwing and ConcurrencyCustom Synchronizers
Starting ThreadsStarting Threads
Executor framework
public interface Executor {
void execute(Runnable command);
}
Executor framework
public interface Executor {
void execute(Runnable command);
}
Executor ExampleExecutor Example
class MyTask implements Runnable {
public void run() {…}
public static void main(…) {
Runnable task1 = new MyTask();
Executor exec = /* */;
exec.execute(task1);
}
}
class MyTask implements Runnable {
public void run() {…}
public static void main(…) {
Runnable task1 = new MyTask();
Executor exec = /* */;
exec.execute(task1);
}
}
1 Thread/ Task1 Thread/ Task
class OnePer implements Executor {
public void Execute(Runnable r){
new Thread(r).start();
}
}
class OnePer implements Executor {
public void Execute(Runnable r){
new Thread(r).start();
}
}
Single ThreadedSingle Threaded
class Just1 implements Executor {
public void Execute(Runnable r){
r.run();
}
}
class Just1 implements Executor {
public void Execute(Runnable r){
r.run();
}
}
Provided Thread Pool Executors
Provided Thread Pool Executors
newFixedThreadPool Bounded size Replace if thread dies
newCachedThreadPool Demand driven variable size
newSingleThreadExecutor Just one thread Replace if thread dies
newScheduledThreadPool Delayed and periodic task execution Good replacement for class Timer
newFixedThreadPool Bounded size Replace if thread dies
newCachedThreadPool Demand driven variable size
newSingleThreadExecutor Just one thread Replace if thread dies
newScheduledThreadPool Delayed and periodic task execution Good replacement for class Timer
Executor Shut-downExecutor Shut-down
Executor is a serice providerExecutor abstracts thread
managementTo maintain the abstraction,
the service should generally provide methods for shutting down the service
JVM cannot shut down until threads do
Executor is a serice providerExecutor abstracts thread
managementTo maintain the abstraction,
the service should generally provide methods for shutting down the service
JVM cannot shut down until threads do
ExecutorServiceExecutorService
public
interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean
awaitTermination(long timeout, TimeUnit unit)throws
InterruptedException;
}
public
interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean
awaitTermination(long timeout, TimeUnit unit)throws
InterruptedException;
}
ExecutorService Notes
ExecutorService Notes
Implies three states:RunningShutting downTerminated
shutdown() runs tasks in queueshutdownNow() returns
unstarted tasksawaitTermination() blocks
until the service is in the terminated state
Implies three states:RunningShutting downTerminated
shutdown() runs tasks in queueshutdownNow() returns
unstarted tasksawaitTermination() blocks
until the service is in the terminated state
ExecutorService implementationExecutorService implementation
ExecutorService is an interface
How do you implement shut down and cancellation?
ExecutorService is an interface
How do you implement shut down and cancellation?
Cancellation in JavaCancellation in Java
Cooperative, not mandatedTraditional method:
interruption
Cooperative, not mandatedTraditional method:
interruptionPublic class Thread { public void interrupt(); public void isInterrupted(); public static boolean interrupted(); …}
InterruptionInterruption
Just a request!Sets a flag that must be
explicitly cleared!Some methods clear the
flag & throw InterruptedException
Others ignore it, leaving other code to handle it
Just a request!Sets a flag that must be
explicitly cleared!Some methods clear the
flag & throw InterruptedException
Others ignore it, leaving other code to handle it
IMPORTANT!IMPORTANT!
Your code should follow protocol when interrupted
If interrupted(),Throw exceptionReset the flag for other code
If InterruptedExceptionPass it alongReset the flag for other code
Don’t swallow, unless your code is handles the interruption policy
Your code should follow protocol when interrupted
If interrupted(),Throw exceptionReset the flag for other code
If InterruptedExceptionPass it alongReset the flag for other code
Don’t swallow, unless your code is handles the interruption policy
Restoring Interrupted Status
Restoring Interrupted Status
catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
// checks (AND CLEARS!) current thread
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
}
catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
// checks (AND CLEARS!) current thread
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
}
Handeling InterruptionHandeling
InterruptionLong computations “break”
to check interrupted statusIf interrupted, stop
computation, throw InterruptedException or restore the interrupted status
Long computations “break” to check interrupted status
If interrupted, stop computation, throw InterruptedException or restore the interrupted status
Interrupting Non-Blocking Operations
Interrupting Non-Blocking Operations
Socket read/writes do not support interruption!If you detect interruption,
close the socket causing read/write to throw an exception
Locks (via synchronized) can not be interruptedExplicit locks beyond scope of
this lecture
Socket read/writes do not support interruption!If you detect interruption,
close the socket causing read/write to throw an exception
Locks (via synchronized) can not be interruptedExplicit locks beyond scope of
this lecture
FutureFuture
Interface representing the lifecycle of a task
Interface representing the lifecycle of a task
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException,
ExecutionException, CancellationException
V get() throws InterruptedException,
ExecutionException, CancellationException,
TimeoutException
}
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException,
ExecutionException, CancellationException
V get() throws InterruptedException,
ExecutionException, CancellationException,
TimeoutException
}
CompletionServiceCompletionService
Combines Executor with BlockingQueue
ExecutorCompletionService
Combines Executor with BlockingQueue
ExecutorCompletionServicepublic interface CompletionService<V> {
Future<V> poll();
Future<V> poll(long timeout, TimeUnit unit);
Future<V> submit(Callable<V> task);
Future<V> submit(Runnable<V> task);
Future<V> take();
}
public interface CompletionService<V> {
Future<V> poll();
Future<V> poll(long timeout, TimeUnit unit);
Future<V> submit(Callable<V> task);
Future<V> submit(Runnable<V> task);
Future<V> take();
}
Futures AgainFutures Again
ExecutorService interface also provides
ExecutorService interface also provides
public interface ExecutorService {
…
Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
Future<T> submit(Runnable task, T result);
}
public interface ExecutorService {
…
Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
Future<T> submit(Runnable task, T result);
}
GUI’sGUI’s
Are almost always single threaded
That is, they have a dedicated thread for the GUI, but just 1!
Multithreaded has been tried, but has generally failed
Are almost always single threaded
That is, they have a dedicated thread for the GUI, but just 1!
Multithreaded has been tried, but has generally failed
Event ProcessingEvent Processing
The Swing apps expect short events that can be processed quickly in sequence
So, long running operations must be executed in another thread
Swing troubles are often related to communication between these threads
The Swing apps expect short events that can be processed quickly in sequence
So, long running operations must be executed in another thread
Swing troubles are often related to communication between these threads
Swing ManipulationSwing Manipulation
Swing does NOT use synchronization, it uses thread confinement
You should almost NEVER create, modify, or query swing components or data models outside the event-dispatching thread
Swing does NOT use synchronization, it uses thread confinement
You should almost NEVER create, modify, or query swing components or data models outside the event-dispatching thread
(A Few Exceptions)(A Few Exceptions)
Some components (see JavaDoc)SwingUtilities.isEventDispatchThr
eadSwingUtilities.invokeLaterSwingUtilities.invokeAndWaitMethods to enqueue repaint or
revalidationMethods for add/remove listeners
Some components (see JavaDoc)SwingUtilities.isEventDispatchThr
eadSwingUtilities.invokeLaterSwingUtilities.invokeAndWaitMethods to enqueue repaint or
revalidationMethods for add/remove listeners
Short-running TasksShort-running Tasks
Short, GUI-confined operations can be programmed entirely in the EDThread
Trivial Example: button that changes color when clicked
Example: information between model and view
Short, GUI-confined operations can be programmed entirely in the EDThread
Trivial Example: button that changes color when clicked
Example: information between model and view
Long-running TasksLong-running Tasks
Proposed Handling:GuiExecutornewCachedThreadPool
Proposed Handling:GuiExecutornewCachedThreadPool
GuiExecutorGuiExecutor import java.util.*; import java.util.concurrent.*;
public class GuiExecutor extends AbstractExecutorService { // Singletons have a private constructor and a public factory private static final GuiExecutor instance = new GuiExecutor();
private GuiExecutor() {}
public static GuiExecutor instance() { return instance; }
public void execute(Runnable r) { if (SwingUtilities.isEventDispatchThread()) r.run(); else SwingUtilities.invokeLater(r); }
/* shutdown, shutdownNow, and awaitTermination throw UnsupportedOperationException for now */
public boolean isShutdown() {return false; }
public boolean isTerminated() {return false; } }
import java.util.*; import java.util.concurrent.*;
public class GuiExecutor extends AbstractExecutorService { // Singletons have a private constructor and a public factory private static final GuiExecutor instance = new GuiExecutor();
private GuiExecutor() {}
public static GuiExecutor instance() { return instance; }
public void execute(Runnable r) { if (SwingUtilities.isEventDispatchThread()) r.run(); else SwingUtilities.invokeLater(r); }
/* shutdown, shutdownNow, and awaitTermination throw UnsupportedOperationException for now */
public boolean isShutdown() {return false; }
public boolean isTerminated() {return false; } }
Long Running Tasks:Starting
Long Running Tasks:Starting
Fire off tasks to thread pool
When completed, use the GuiExecutor to send a task for updating gui
Simple example: status text
Fire off tasks to thread pool
When completed, use the GuiExecutor to send a task for updating gui
Simple example: status text
Long-running Tasks:Cancellation
Long-running Tasks:Cancellation
Instead of execute(), use submit()
Returns a Future<V> that is cancelable
You still have to make your task interruptable
Instead of execute(), use submit()
Returns a Future<V> that is cancelable
You still have to make your task interruptable
Long-running Tasks:Visual Feedback
Long-running Tasks:Visual Feedback
The books method:Create a task subclass with
some methods callable from EDthread, & others callable elsewhere
I think this is dangerous. If you’re going to do this, you shouldClearly document the methodsCheck if you’re in the Edthread
The books method:Create a task subclass with
some methods callable from EDthread, & others callable elsewhere
I think this is dangerous. If you’re going to do this, you shouldClearly document the methodsCheck if you’re in the Edthread
BackgroundTask<V>BackgroundTask<V>
Code is confusing, hard to follow
If you want to look at it:
Code is confusing, hard to follow
If you want to look at it:www.javaconcurrencyinpractice.com/listings/BackgroundTask.java
Simpler SolutionSimpler Solution
Design LR tasks with “hooks”The hook can be a special
communication classWhen checking for
cancellation, update the hookHook schedules update to
GUI
Design LR tasks with “hooks”The hook can be a special
communication classWhen checking for
cancellation, update the hookHook schedules update to
GUI
Last NotesLast Notes
Writing your own synchronizers
Writing your own synchronizers // BLOCKS-UNTIL: not-full
public synchronized void put(V v) throws InterruptedException { while (isFull()) wait(); doPut(v); notifyAll(); }
// BLOCKS-UNTIL: not-empty public synchronized V take() throws InterruptedException { while (isEmpty()) wait(); V v = doTake(); notifyAll(); return v; }