Download PPT

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Concurrency (p2)
synchronized (this) {
doLecture(part2);
}
Quick Review
 Threads can up performance
 Java’s 2 parts for thread safety
Atomicity
Visibility
 Java’s Primitives
volatile
synchronized
 Library Support
Atomic variables
Concurrent collections
Common synchronizers (BlockingQueue)
Outline
Executor Framework
Shutdown and cancellation
Swing and Concurrency
Custom Synchronizers
Starting Threads
Executor framework
public interface Executor {
void execute(Runnable command);
}
Executor Example
class MyTask implements Runnable {
public void run() {…}
public static void main(…) {
Runnable task1 = new MyTask();
Executor exec = /* */;
exec.execute(task1);
}
}
1 Thread/ Task
class OnePer implements Executor {
public void Execute(Runnable r){
new Thread(r).start();
}
}
Single Threaded
class Just1 implements Executor {
public void Execute(Runnable r){
r.run();
}
}
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
Executor Shut-down
Executor is a serice provider
Executor abstracts thread
management
To maintain the abstraction, the
service should generally provide
methods for shutting down the
service
JVM cannot shut down until threads
do
ExecutorService
public
interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean
awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
}
ExecutorService Notes
Implies three states:
Running
Shutting down
Terminated
shutdown() runs tasks in queue
shutdownNow() returns unstarted
tasks
awaitTermination() blocks
until the service is in the
terminated state
ExecutorService
implementation
ExecutorService is an interface
How do you implement shut
down and cancellation?
Cancellation in Java
Cooperative, not mandated
Traditional method: interruption
Public class Thread {
public void interrupt();
public void isInterrupted();
public static boolean interrupted();
…
}
Interruption
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!
Your code should follow protocol
when interrupted
If interrupted(),
Throw exception
Reset the flag for other code
If InterruptedException
Pass it along
Reset the flag for other code
Don’t swallow, unless your code is
handles the interruption policy
Restoring Interrupted
Status
catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
// checks (AND CLEARS!) current thread
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
}
Handeling Interruption
Long computations “break” to
check interrupted status
If interrupted, stop
computation, throw
InterruptedException or
restore the interrupted status
Interrupting NonBlocking 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 interrupted
Explicit locks beyond scope of
this lecture
Future
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
}
CompletionService
Combines Executor with
BlockingQueue
ExecutorCompletionService
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 Again
ExecutorService interface also
provides
public interface ExecutorService {
…
Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
Future<T> submit(Runnable task, T result);
}
GUI’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
Event 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
Swing 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
(A Few Exceptions)
Some components (see JavaDoc)
 SwingUtilities.isEventDispatchThrea
d
 SwingUtilities.invokeLater
 SwingUtilities.invokeAndWait
Methods to enqueue repaint or
revalidation
Methods for add/remove listeners
Short-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
Long-running Tasks
Proposed Handling:
GuiExecutor
newCachedThreadPool
GuiExecutor


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
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
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
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
should
Clearly document the methods
Check if you’re in the Edthread
BackgroundTask<V>
Code is confusing, hard to follow
If you want to look at it:
www.javaconcurrencyinpractice.com/listings/BackgroundTask.java
Simpler Solution
Design LR tasks with “hooks”
The hook can be a special
communication class
When checking for
cancellation, update the hook
Hook schedules update to GUI
Last Notes
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;
}