250 likes | 356 Views
CSCI 6900: Design, Implementation, and Verification of Concurrent Software. Eileen Kraemer August 24 th , 2010 The University of Georgia. Java Threads & Concurrency, continued. Liveness Deadlock Starvation and Livelock Guarded Blocks Immutable Objects A Synchronized Class Example
E N D
CSCI 6900: Design, Implementation, and Verification of Concurrent Software Eileen Kraemer August 24th, 2010 The University of Georgia
Java Threads & Concurrency, continued • Liveness • Deadlock • Starvation and Livelock • Guarded Blocks • Immutable Objects • A Synchronized Class Example • A Strategy for Defining Immutable Objects • High Level Concurrency Objects • Lock Objects • Executors • Executor Interfaces • Thread Pools • Concurrent Collections • Atomic Variables
Executors • Separate thread management & control from the rest of the app • Separation of concerns • Reusability • Executor Interfaces • Three kinds of object types • Thread pools • Most common implementation of executor
Executor Interfaces • Executor • ExecutorService • ScheduledExecutorService
The Executor Interface • See: java.util.concurrent Interface Executor • An “executor” is an object that executes submitted Runnable tasks. • Separates task submission from details of how to schedule & run
Contains one method: execute void execute(Runnable command) Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation. Parameters: command - the runnable task Throws: RejectedExecutionException- if this task cannot be accepted for execution. NullPointerException- if command is null
Instead of writing • new Thread(new(RunnableTask1())).start(); • new Thread(new(RunnableTask2())).start(); • Each of which creates a new thread and launches it immediately
Write: • Executor executor = anExecutor(); • executor.execute(new RunnableTask1()); • executor.execute(new RunnableTask2()); • Depending on the implementation of the Executor interface, the thread may use an existing thread, place r in a queue to wait for a worker thread, etc.
This executor runs the submitted task in the caller’s thread … class DirectExecutor implements Executor { public void execute(Runnable r) { r.run(); } }
This one spawns a new thread to execute the task … class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { new Thread(r).start(); } }
Others may impose some limitation on how and when tasks are scheduled. • See example SerialExecutor • serializes submission of tasks to second executor
The ExecutorService Interface • Extends the Executor Interface • Adds methods for: • submit • accepts Runnable and Callable (can return a value) objects • returns a Future object • allows the submission of collections of Callable objects • invokeAll, invokeAny • shutdown • awaitTermination • isShutdown, isTerminated
The ScheduledExecutorService Interface • Offers a schedule method • Executes a Runnable or Callable task after a specified delay • Also • scheduleAtFixedRate • scheduleWithFixedDelay
Thread Pools • Worker threads • Used to execute multiple tasks • Minimizes overhead of thread creation
java.util.concurrent.Executors • Contains factory and utility methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes • Methods that create and return an ExecutorService set up with commonly useful configuration settings. • Methods that create and return a ScheduledExecutorService set up with commonly useful configuration settings. • Methods that create and return a "wrapped" ExecutorService, that disables reconfiguration by making implementation-specific methods inaccessible. • Methods that create and return a ThreadFactory that sets newly created threads to a known state. • Methods that create and return a Callable out of other closure-like forms, so they can be used in execution methods requiring Callable.
Fixed thread pool • Maintains a fixed number of worker threads • An internal queue holds submitted tasks • Holds tasks when #tasks > #threads • Advantages • Applications degrade gracefully • By limiting resources consumed by threads to fixed number
newFixedThreadPool factory method • Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. • At any point, at most n Threads threads will be actively processing tasks. • If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. • If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. • The threads in the pool will exist until it is explicitly shutdown.
newCachedThreadPool • creates an executor with an expandable thread pool. • suitable for applications that launch many short-lived tasks.
newSingleThreadExecutor • creates an executor that executes a single task at a time.
Concurrent Collections • Help avoid memory consistency errors • Define a happens-before relationship between an operation that adds an object to the collection and and subsequent operations that remove the object • BlockingQueue • ConcurrentMap • ConcurrentNavigableMap
BlockingQueue • defines a first-in-first-out data structure that • blocks or times out when you attempt to • add to a full queue, or • retrieve from an empty queue.
ConcurrentMap • a subinterface of java.util.Map • defines useful atomic operations. • remove or replace a key-value pair only if the key is present, • add a key-value pair only if the key is absent. • The standard general-purpose implementation of ConcurrentMap is ConcurrentHashMap, which is a concurrent analog of HashMap.
ConcurrentNavigableMap • a subinterface of ConcurrentMap • supports approximate matches. • The standard general-purpose implementation of ConcurrentNavigableMap is ConcurrentSkipListMap, which is a concurrent analog of TreeMap.
Atomic Variables – java.util.concurrent.atomic • defines classes that support atomic operations on single variables. • have get and set methods that work like reads and writes on volatile variables. • a set has a happens-before relationship with any subsequent get on the same variable. • compareAndSetmethod • simple atomic arithmetic methods for integer atomic variables.
Next steps… • Read Ch. 2 of Magee and Kramer, Processes and Threads