OCP Flashcards – 10. Java Concurrency

OCP Exam Objective 10 – Java Concurrency

Flashcard OCP.10.Java.Concurrency.001

How would you create classes that are capable of multi-threading?

Click here to view answer
By directly implementing the Runnable interface or by extending the Thread class (which itself is a Runnable).

 

Flashcard OCP.10.Java.Concurrency.002

Which method must be implemented/overridden when defining a multi-threading class?

Click here to view answer
One needs always override the run() method, otherwise it’ll do nothing.

 

Flashcard OCP.10.Java.Concurrency.003

Which method should be called by the code so that a task is executed?

Click here to view answer
Code should call the start() method rather than run(), which will be then invoked by the JVM itself.

 

Flashcard OCP.10.Java.Concurrency.004

What is the difference between the Runnable and Callable interfaces?

Click here to view answer
The Callable interface also represents a task that needs to be completed by a thread, however, unlike Runnable‘s run(), which is void, the call() method of a Callable implementation returns a value. What’s more, it can throw an Exception when unable to compute the result.

 

Flashcard OCP.10.Java.Concurrency.005

What is the Executor interface?

Click here to view answer
An object of this type executes submitted Runnable tasks. The Executor takes care of the lower-level details of multi-threaded programming (such as how each task will be run, including details of thread use, scheduling, etc.), by offering high-level user-friendly concurrency constructs.

 

Flashcard OCP.10.Java.Concurrency.006

What is the ExecutorService interface?

Click here to view answer
ExecutorService provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

 

Flashcard OCP.10.Java.Concurrency.007

What are primary methods of the ExecutorService interface?

Click here to view answer
<T> Future<T> submit(Callable<T> task) Submits a value-returning task for execution and returns a Future representing the pending results of the task.
void execute(Runnable command) Executes the given command at some time in the future.
(Inherited from the java.util.concurrent.Interface Executor interface)
Future<?> submit(Runnable task) Submits a Runnable task for execution and returns a Future representing that task.
<T> Future<T> submit(Callable<T> task) Submits a value-returning task for execution and returns a Future representing the pending results of the task.
void shutdown() Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
boolean awaitTermination(long timeout, TimeUnit unit) Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first. Returns true if terminated before the timeout has elapsed.

 

Flashcard OCP.10.Java.Concurrency.008

What is the Future datatype?

Click here to view answer
It’s an interface that is used as a container to represent the result of an asynchronous computation. Allows to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation by using method get(), blocking if necessary until it is ready.

 

Flashcard OCP.10.Java.Concurrency.009

What is the purpose of the Executors class?

Click here to view answer
The Executors class provides factory methods to create a variety of ExecutorService objects, for example:

ExecutorService exec1 = Executors.newFixedThreadPool(2);
ExecutorService exec2 = Executors.newCachedThreadPool();

 

Flashcard OCP.10.Java.Concurrency.010

What is race condition?

Click here to view answer
When two or more threads are trying to access a variable and one of them wants to modify it, we get a problem known as a race condition because, depending on the order of execution, the variable’s value can be different.

 

Flashcard OCP.10.Java.Concurrency.011

What is critical section?

Click here to view answer
The section of code that is commonly accessed and modified by more than one thread.

 

Flashcard OCP.10.Java.Concurrency.012

How to access shared values while avoiding race conditions?

Click here to view answer
One needs to ensure that the critical section is executed by only one thread at a time. This is known as thread synchronization (that is, locks), which provides protected access to shared resources by means of synchronized blocks and synchronized methods.

 

Flashcard OCP.10.Java.Concurrency.013

How do we achieve thread synchronization?

Click here to view answer
This is done by acquiring a lock on the object using the synchronized keyword, which means that only a single thread can acquire a lock on an object at a time, and only that thread can execute the block of code (that is, the critical section) protected by the lock. Until then, the other threads have to wait.

 

Flashcard OCP.10.Java.Concurrency.014

What is a common problem associated with locks?

Click here to view answer
A deadlock.

 

Flashcard OCP.10.Java.Concurrency.015

What’s a deadlock?

Click here to view answer
A deadlock typically happens when two threads acquire locks in opposite order. When one thread has acquired one lock and waits for another lock to be opened, another thread has already acquired that other lock and itself waits for the first lock to be released. As a result, no progress is made: the program deadlocks.

 

Flashcard OCP.10.Java.Concurrency.016

What’s a livelock?

Click here to view answer
When a change done by a thread is repeatedly undone by another thread, both threads are busy but the application as a whole does not make progress; this situation is known as a livelock.

 

Flashcard OCP.10.Java.Concurrency.017

What’s a starvation?

Click here to view answer
The situation in which low-priority threads “starve” for a long time trying to obtain access to a shared resource.

 

Flashcard OCP.10.Java.Concurrency.018

What types accept the synchronized keyword?

Click here to view answer
Reference types, in other words, objects. You cannot synchronize on primitives.

 

Flashcard OCP.10.Java.Concurrency.019

How would you synchronize on this object?

Click here to view answer
For example:

synchronized(this) {
    // do your job
}

 

Flashcard OCP.10.Java.Concurrency.020

How would you synchronize an instance method?

Click here to view answer
For example:

private int myValue;
public synchronized void assign(int i) {
    myValue = i;
}

 

Flashcard OCP.10.Java.Concurrency.021

How would you synchronize a static method?

Click here to view answer
Since static methods cannot reference this, we’ll need declare the variable static as in:

private static int myValue;
public static synchronized void assign(int i) {
    myValue = i;
}

In the above example, the assign() method acquires a lock on the Test.class object when it is called. An equivalent method by using a synchronized block would be as follows:

class Test {
    private static int myValue;
    public static void assign(int i) {
        synchronized(Test.class) {
            myValue = i;
       }
    }
    // more members
}

 

Flashcard OCP.10.Java.Concurrency.022

Can constructors be synchronized and why it is so?

Click here to view answer
No, an attempt to synchronize a ctor will flag a comperr because the JVM guarantees that only one thread can invoke a specific constructor at a given point in time. It is possible, however, to place synchronized blocks inside constructors.

 

Flashcard OCP.10.Java.Concurrency.023

How would you demonstrate the use of synchronization in a real-world example?

Click here to view answer
This would be a typical scenario for the Singleton Design Pattern:

class Singleton {
    private static volatile Singleton instance;
    private Singleton() { }

/* 1ST APPROACH
 * Will create multiple instances if several threads access this method at the same time
 */
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
       return instance;
    }

/* 2ND APPROACH
 * Thread-safe and creates only one instance of Singleton even in a concurrent environment
 * but can be too expensive due to cost of synchronization at every call
 */
    synchronized public static Singleton getInstanceThreadSafe() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

/* 3RD APPROACH
 * Also known as Double Checked Locking.
 * Minimizes cost of synchronization and improves performance by locking only critical section of code
 * (that is, where instance of Singleton class gets created).
 */
    public static Singleton getInstanceDoubleCheckedLocking() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

 

Flashcard OCP.10.Java.Concurrency.024

Performing locking and unlocking to process primitives is inefficient. What is a better alternative to achieve thread synchronization in such cases?

Click here to view answer
One should use atomic variables provided by the classes such as AtomicInteger defined in the java.util.concurrent.atomic package.

 

Flashcard OCP.10.Java.Concurrency.025

What is the difference between the incrementAndGet() and getAndIncrement() methods defined in the AtomicInteger class?

Click here to view answer
Both methods atomically increment the variable on which they have been called but getAndIncrement() returns the old value while incrementAndGet() returns the updated value. Also note that the use of atomic types still does not guarantee the order in which they are processed by multiple threads.

 

Flashcard OCP.10.Java.Concurrency.026

What is a CyclicBarrier?

Click here to view answer
CyclicBarrier is a synchronization aid that enables a set of threads (called party) to wait for each other at a predefined execution point. CyclicBarriers are useful in programs involving a fixed sized party of threads. The barrier is called cyclic because it can be re-used after the waiting threads are released.

 

Flashcard OCP.10.Java.Concurrency.027

What is the java.util.concurrent package?

Click here to view answer
This package provides a number of classes that are thread-safe equivalents of the ones available in the Java Collections Framework (that is, in the java.util package); for example, java.util.concurrent.ConcurrentHashMap is a concurrent equivalent to java.util.HashMap.

 

Flashcard OCP.10.Java.Concurrency.028

What is the java.util.concurrent.CopyOnWriteArrayList class and what does it do?

Click here to view answer
This class is similar to ArrayList, but provides safe concurrent access. When you modify a CopyOnWriteArrayList with a mutative operation such as add(), set(), etc., a fresh copy of the underlying array is created.

 

Flashcard OCP.10.Java.Concurrency.029

What is the Fork/Join Framework?

Click here to view answer
The FJF is an implementation of the ExecutorService interface and provides an easy-to-use concurrent platform in order to exploit multiple processors with decent parallelism. This framework is useful for modeling divide-and-conquer problems.

 

Flashcard OCP.10.Java.Concurrency.030

What is the Fork/Join Framework based on?

Click here to view answer
The FJF employs the work-stealing algorithm: when a worker thread completes its work and becomes free, it takes (or “steals”) work from other threads that are still busy. The work-stealing technique results in decent load balancing thread management with minimal synchronization cost.

 

Flashcard OCP.10.Java.Concurrency.031

What is the primary class in the Fork/Join Framework that executes tasks and manages their lifecycles?

Click here to view answer
It’s ForkJoinPool, which is a thread pool for running fork/join tasks. It executes an instance of the ForkJoinTask type.

 

Flashcard OCP.10.Java.Concurrency.032

What is ForkJoinTask?

Click here to view answer
ForkJoinTask<V> is a lightweight abstract thread-like entity representing a task that defines methods such as fork() and join(). It is serializable and implements Future<V>.

 

Flashcard OCP.10.Java.Concurrency.033

What do parallel streams do?

Click here to view answer
Parallel streams split the elements into multiple chunks, process each chunk with different threads, and, if necessary, combine the results from those threads into a final result.

 

Flashcard OCP.10.Java.Concurrency.034

What do you get by calling the stream() method on a Collection class?

Click here to view answer
This method produces a sequential stream, whilst by calling the parallelStream() method you will get a parallel stream.

 

Flashcard OCP.10.Java.Concurrency.035

True or false: Parallel streams internally use the Fork/Join Framework?

Click here to view answer
True. Note, however, that in order to use parallel streams correctly, the process steps should consist of stateless and independent tasks.

 

Flashcard OCP.10.Java.Concurrency.036

Is it possible to convert a sequential stream to a parallel stream, and vice versa?

Click here to view answer
Yes, it is. To do so, call the parallel() method; similarly, to convert a parallel stream to a sequential stream, we call the sequential() method.

 

Flashcard OCP.10.Java.Concurrency.037

How to check if the stream is sequential or parallel?

Click here to view answer
By calling the isParallel() method.

 

Flashcard OCP.10.Java.Concurrency.038

Which ExecutorService method supports only Runnable objects?

Click here to view answer
execute()

 

Flashcard OCP.10.Java.Concurrency.039

Which ExecutorService method supports both Runnable and Callable objects?

Click here to view answer
submit()

 

Flashcard OCP.10.Java.Concurrency.040

What is the RecursiveTask class?

Click here to view answer
A recursive result-bearing implementation of ForkJoinTask.

 

Flashcard OCP.10.Java.Concurrency.041

Which RecursiveTask method returns the final result after all worker threads have completed their work?

Click here to view answer
join()

 

Flashcard OCP.10.Java.Concurrency.042

Which RecursiveTask method returns a computational result using the fork/join strategy?

Click here to view answer
compute()

 

Leave Comment

Your email address will not be published.