1 / 34

Concurrency (p2)

This article provides a quick review of concurrency and thread safety in Java, covering topics such as atomicity, visibility, synchronized, volatile, and library support. It also discusses thread pooling, executor framework, shutdown and cancellation, and concurrency in Swing applications.

ncarrie
Download Presentation

Concurrency (p2)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. 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)

  3. Outline • Executor Framework • Shutdown and cancellation • Swing and Concurrency • Custom Synchronizers

  4. Starting Threads • Executor framework public interface Executor { void execute(Runnable command); }

  5. Executor Example class MyTask implements Runnable { public void run() {…} public static void main(…) { Runnable task1 = new MyTask(); Executor exec = /* */; exec.execute(task1); } }

  6. 1 Thread/ Task class OnePer implements Executor { public void Execute(Runnable r){ new Thread(r).start(); } }

  7. Single Threaded class Just1 implements Executor { public void Execute(Runnable r){ r.run(); } }

  8. 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

  9. 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

  10. ExecutorService public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; }

  11. 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

  12. ExecutorService implementation • ExecutorService is an interface • How do you implement shut down and cancellation?

  13. Cancellation in Java • Cooperative, not mandated • Traditional method: interruption Public class Thread { public void interrupt(); public void isInterrupted(); public static boolean interrupted(); … }

  14. 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

  15. 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

  16. Restoring Interrupted Status catch(InterruptedException e) { Thread.currentThread().interrupt(); } // checks (AND CLEARS!) current thread if (Thread.interrupted()) { Thread.currentThread().interrupt(); }

  17. Handeling Interruption • Long computations “break” to check interrupted status • If interrupted, stop computation, throw InterruptedException or restore the interrupted status

  18. 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 interrupted • Explicit locks beyond scope of this lecture

  19. 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 }

  20. 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(); }

  21. 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); }

  22. 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

  23. 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

  24. 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

  25. (A Few Exceptions) • Some components (see JavaDoc) • SwingUtilities.isEventDispatchThread • SwingUtilities.invokeLater • SwingUtilities.invokeAndWait • Methods to enqueue repaint or revalidation • Methods for add/remove listeners

  26. 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

  27. Long-running Tasks • Proposed Handling: • GuiExecutor • newCachedThreadPool

  28. 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; } • }

  29. 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

  30. Long-running Tasks:Cancellation • Instead of execute(), use submit() • Returns a Future<V>that is cancelable • You still have to make your task interruptable

  31. 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

  32. BackgroundTask<V> • Code is confusing, hard to follow • If you want to look at it: www.javaconcurrencyinpractice.com/listings/BackgroundTask.java

  33. 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

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

More Related