OCP - 3

Concurrency & IO

Concurrency & IO


Fichier Détails

Cartes-fiches 110
Langue English
Catégorie Informatique
Niveau Autres
Crée / Actualisé 08.03.2019 / 08.01.2020
Lien de web
https://card2brain.ch/box/20190308_ocp_3
Intégrer
<iframe src="https://card2brain.ch/box/20190308_ocp_3/embed" width="780" height="150" scrolling="no" frameborder="0"></iframe>

What is the relation between a Task and a Thread?

A task is a single unit of work performed by a thread. A thread can implement multiple independent tasks but only one task at a time. In Java, such a Task is usually defined as an implementation of the Runnable Interface.

What is the signature of the Runnable interface?

One single abstract method: void run();

How can you start a new Tread?

  1. Configure the Tread class by either passing a Runnable Object in the Thread constructor or by extending the Thread class and overriding the run method
  2. Calling the start Method on the Thread instance

What is always important in concurrent applications?

Never make assumptions on the order of execution of Threads and tasks. This is the responsibility of the operating system and you cannot assume anything!

What is more prefereable for implementing a Task, extending Thread or implementing Runnable?

Almost always the Runnable class. THread might be useful for complex rules upon which multiple tasks rely.

The runnable class is preferable becauase of single inheritance and the use of the Concurrency API

What is Thread.sleep(int) for and when should it be used?

While waiting for the result of another thread, it might be necessary to poll for the Results of the other Thread. Using just a while loop is not only wasted energy but also a potential infinite loop. By using Thread.sleep, the current thread is paused for the defined amount of time, allowing other threads to do their work.

What has to be minded when using the Thread.sleep method?

It declares the checked InterruptedException which must be handeled

What is the ExecutorService Class for?

It simplifies the execution of concurrent tasks by abstracting common error-prone operations

What is important when using the ExecutorService class?

It is important to call the shutdown() method. A thread executor creates a non-demon thread on the first task that is executed, so failing to call shutdown will result in you application never terminating.

What assumption can be made, when using the a single-threaded executor service?

All Tasks that are queued are executed in the order in which they were added to the executor service

What is the ExecutorService lifecycle?

  • After construction, an ExecutorService is active, meaning it accepts new tasks and executes tasks.
  • After calling shutdown(), an ExecutorService is shutting down, meaning it rejects new tasks and executes tasks.
  • After all Tasks are finished,  an ExecutorService is terminated, meaning it rejects new tasks and no tasks are running

What does the ExecutorService.shutdownNow() method do?

  • It attempts to stop all running tasks (NO Guarantees)
    • Typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
  • This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.
  • No new tasks are started and all queued, unexecuted Tasks are returned

What common ExecutorService methods for launching Tasks exist?

  • Future<?> submit(Runnable task)
  • <T> Future<T> submit(Callable<T> task)
  • <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException
  • <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException

What is the difference between execute and submit on the ServiceExecutor class?

  • execute is fire and forget - has no return type. It accepts a Runnable Instance, meaning that the implementation cannot throw a checked exception
  • submit returns a Future to access it's result. It accepts a Calleable Instance, meaning that the implementation can throw a checked exception

How does the ExecutorService.invokeAll method beahve?

  • It executes the given task synchronously!
    •  Future.isDone() is true for each element of the returned list.
  • The result is a list of all task results as a Collection of futures
    • Same order as the original collection

How does the ExecutorService.invokeAny method beahve?

  • It executes the given tasks synchronously
  • The result is the Result one of th the finished tasks
    • It is not guaranteed that the result of the Task that terminates first is used!
  • All unfinished tasks are canceled

What are common Methods on the Future methods?

  • isDone
  • isCancelled
  • cancel
  • V get()
  • V get(long timeout, TimeUnit unit)

when does Future.isDone return true?

When the task was completed, threw an exception or was cancelled

What does Future.get do?

  • Without a timeout: Retreives the result of a task, waiting endlessly if it is not yet available
  • With a timeout: Throws a checked TimeoutException when the result is not ready by the time the timeout is reached

What is the difference between Runnable and Callable?

Callable can return a value and allows a throws declaration of Exception

@FunctionalInterface Callable<V> { V call() throws Exception;}

@FunctionalInterface Runnable { void run()}

How can you resolve ambiguity of lambda expressions, i.e. Callable vs. Supplier

It can be resulved with an explicit cast:

use((Callable<Integer>)() -> {throws new IOException("");}};

What does the ExecutorService.awaitTermination(...) method do?

  • Blocks until all tasks have completed execution after a shutdown request
  • or the timeout occurs
  • or the current thread is interrupted
  • whichever happens first!

What common Methods exist on the ScheduledExecutorService exist? How do they differ?

  • schedule(Callable<V> callable, long delay, TimeUnit unit)

    • Run after a given delay(Think "setTimeout")

  • schedule(Runnable callable, long delay, TimeUnit unit)

    • Run after a given delay (Think "setTimeout")

  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

    • Run after a given delay (Think "setTimeout")

    • Create a new task every period value that passes (Think "setInterval")

  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

    • Run after a given delay (Think "setTimeout")

    • Create a delayed task with after the the termination of the previous one

Why do scheudleAtFixedRate and scheduleAtFixedDelay only accept a Runnable and not a Callable instance?

Since they can run ininitely, the result will never be available, making Runnable the only valid option

What commonmethod exist on the Executors factory class? How do they differ

  • ExecutorService newSingleThreadExecutor()
  • ScheduledExecutorService newSingleThreadScheduledExecutor()
  • ExecutorService newCachedThreadPool()
    • Create new Threads when none available, but reuse existing, unused Thread instances when idle
  • ExecutorService newFixedThreadPool(int nThreads)
    • Fixed number of threads
  • ScheduledExecutorService ScheduledThreadPool(int nThreads)
    • Fixed number of threads + Scheduling

When is the use of Executors.newCachedThreadPool() appropriate?

Only for man short-lived async tasks.

What common tools does java offer to prevent race conditions?

  • Monitor using the synchronized keyword = Locking
  • Atomic clases that provide atomic operations

Wat common Atomic classes exist?

  • AtomicBoolean
  • AtomicInteger
  • AtomicIntegerArray
  • AtomicLong
  • AtomicLongArray
  • AtomicReference (Object Reference)
  • AtomicReferenceAray

What commmon atomic methods exist?

  • get
  • set
  • getAndSet
  • incrementAndGet
  • getAndIncrement
  • decrementAndGet
  • getAndDecrement

What's wrong here?

for(int i=0;i<10;i++){
  synchronized(manager){
    service.submit(() -> manager.increment());
  }
}

The creation of the threads is synchronized but not the execution!

Does synchronized work on static methods?

Yes, the class object is used for locking

What are concurrent collections for?

They offer convenience and prevent error prone implementations and avoid unnecessary synchronisation

What are memory consistency errors?

A memory consitency error occurs, when two threads have incosistent views of what should be the same data. In the context of Collections, a common error is concurrent modification (ConcurrentModificationException)

What common concurrent classes exist?

  • ConcurrentHasMap
  • ConcurrentLinkedDeque
  • ConcurrentLinkedQueue
  • ConcurrentSkipListMap
  • ConcurrentSkipListSet
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet
  • LinkedBlockingDeque
  • LinkedBlockingQueue

What is the difference between a BlockingQueue/BlockingDeque and "normal" Queue/Deque?

The Blocking versions offer additional methods that will wait for a specific amount of time to complete an operation:

eg. boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException -> Returns false on timeout

eg. E poll(long timeout, TimeUnit unit) throws InterruptedException -> Returns null on timeout

What are the concurrent SkipLists for?

Thei offer sorted (natural ordering) concurrent collections, making them the concurrent counterparts of TreeSet and TreeMap

How do CopyOnWrite Collections work?

The underlying data is copied when the collection changes. When using an iterator, the underlying values do not change, eg:

List<Integer> list = new CopyOnWriteArrayList<>(Arrays.asList(4,3,52));
for(Integer item:list){
  list.add(9); // Neither a ConcurrentModification is thrown nor does a infinite loop result
}

What are the synchronized methods on the Collections class for, eg synchronizedCollection?

They wrap a non-concurrent implementation of a collection in a thread-safe version. This is convenient but less efficient that using a concurrent implementation instead.

Also: These wrapper functions do not synchronize iterators, meaning that you have to use a monitor when iterating over a collection!

What is the main difference betwen a serial stream an a parallel stream?

Seria streams are ordered whereas parallel streams are not necessarily

How can you construct a parallel stream?

Either use .parallel() on an existing stream or use the parallelStream() method on the Collection instance