Concurrency (p2) synchronized (this) { doLecture(part2); } synchronized (this) { doLecture(part2); }

Post on 14-Dec-2015

250 views 6 download

transcript

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; }