Java concurrency interview questions github

Spike 195 Published: 07/27/2024

Java concurrency interview questions github

Here are some common Java concurrency interview questions and answers:

1. What is thread-safe?

A: A piece of code is said to be thread-safe if it can be executed by multiple threads simultaneously without causing any issues or errors.

2. What is the difference between synchronized and volatile keywords in Java?

A: The synchronized keyword is used to ensure that only one thread can execute a block of code at a time, while the volatile keyword is used to indicate that a variable's value may change suddenly.

3. What are the different types of concurrency models in Java?

A: There are three main concurrency models in Java:

Reentrant Locks: Allows multiple threads to share a lock, but only one thread can hold the lock at a time. Semaphores: Allows multiple threads to access a shared resource by implementing a queue-based mechanism. Monitors: Provides a way for multiple threads to share resources by using locks and condition variables.

4. What is ReentrantLock in Java?

A: A reentrant lock allows multiple threads to share the same lock, but only one thread can hold the lock at a time. It's useful when you need to implement mutual exclusion or serialization of access to shared resources.

5. How do you handle a situation where two or more threads try to update the same variable concurrently?

A: To handle this situation, you can use AtomicInteger or other atomic variables, which provide operations like incrementAndGet() and compareAndSet(). These operations ensure that updates are performed atomically, preventing inconsistent state.

6. What is a Semaphore in Java?

A: A semaphore in Java is a synchronization primitive that allows multiple threads to access a shared resource by implementing a queue-based mechanism. It's useful when you need to limit the number of concurrent accesses to a shared resource.

7. Can you give an example of using CountDownLatch in Java?

A: A CountDownLatch can be used to synchronize threads that need to wait for each other to complete some tasks before proceeding further. For example, if you have a group of threads that need to wait until all of them have completed their tasks before proceeding, you can use a CountDownLatch.

8. What is CopyOnWriteArrayList in Java?

A: A CopyOnWriteArrayList is a thread-safe variant of the ArrayList class. It provides an efficient way to iterate over the elements in the list without blocking other threads from modifying the list concurrently.

9. Can you explain the concept of livelock in Java concurrency?

A: A livelock occurs when multiple threads are competing for a shared resource, but none of them can make progress because they're all waiting for each other to complete some task. This results in an infinite loop of thread contention and no meaningful work gets done.

10. How do you handle the situation where one thread is holding onto a lock while another thread needs access to that same lock?

A: To handle this situation, you can use Lock implementations like ReentrantLock, which allow other threads to interrupt the current thread's lock hold and take control of the lock.

Here are some sample codes for these questions:

ConcurrentHashMap vs Synchronized HashMap Java Concurrency: Thread Pool vs Executor Service Java Concurrency: Deadlock Example

Note that the codes are not exhaustive, but they provide a starting point for understanding and implementing concurrency concepts in Java.

I hope this helps!

Java CompletableFuture Interview Questions

Here are some Java CompletableFuture interview questions:

1. What is the main difference between CompletableFuture and a traditional callback-based approach?

Java 8 introduced the concept of CompletionStage to handle asynchronous programming. CompletableFuture is one implementation of this interface, which allows you to write asynchronous code that is more concise and easier to read than traditional callback-based approaches.

2. How do you handle exceptions in a CompletableFuture chain?

When handling exceptions in a CompletableFuture chain, you should use the handle() or exceptionally() method to specify a fallback or error-handling mechanism. If an exception occurs, the CompletableFuture will complete with that exception.

3. Can you give an example of how to use thenApply() to transform a result?

Suppose we have a CompletableFuture that represents a network request. We can use thenApply() to convert the response from the network request into a custom Java object:

CompletableFuture future = ...;

String transformedResult = future.thenApply(response -> {

// Transform the response into a custom Java object

return new CustomObject(response);

}).get();

4. How do you cancel a CompletableFuture?

You can use the cancel() method to cancel a CompletableFuture:

CompletableFuture future = ...;

// Cancel the CompletableFuture

future.cancel(true);

// If the CompletableFuture is already completed, this has no effect

5. Can you explain the difference between thenAccept() and thenApply()?

thenAccept() and thenApply() both transform a value, but they differ in their behavior when an exception occurs:

CompletableFuture future = ...;

// When an exception occurs:

future.thenAccept(result -> {

// This code will not be executed if an exception occurs

}).exceptionally(ex -> {

// Handle the exception here

});

// When an exception occurs:

future.thenApply(result -> {

// This code will not be executed if an exception occurs, but you can handle it in an exception handler

return null;

}).exceptionally(ex -> {

// Handle the exception here

});

6. How do you use thenCombine() to combine two CompletableFutures?

Suppose we have two CompletableFutures that represent independent network requests. We can use thenCombine() to create a new CompletableFuture that represents the combination of these two requests:

CompletableFuture future1 = ...;

CompletableFuture future2 = ...;

// Combine the results using thenCombine()

CompletableFuture combinedFuture = future1.thenCombine(future2, (result1, result2) -> {

// Combine the results here

return new Object(result1, result2);

});

7. Can you explain how to use thenCompose()?

thenCompose() is a way to combine two CompletableFutures using a function:

CompletableFuture future = ...;

// Use thenCompose() with a function that returns another CompletableFuture

future.thenCompose(result -> {

// Create a new CompletableFuture based on the result

return CompletableFuture.supplyAsync(() -> {

// Perform some asynchronous operation here

return "New Result";

});

});

8. How do you use toCompletableFuture() to convert a Future to a CompletableFuture?

To convert a Future to a CompletableFuture, you can use the toCompletableFuture() method:

Future future = ...;

// Convert the Future to a CompletableFuture

CompletableFuture completableFuture = future.toCompletableFuture();

9. Can you explain how to use runAfterEither()?

runAfterEither() is used to execute some code after either the main or dependent CompletableFutures have completed:

CompletableFuture future1 = ...;

CompletableFuture future2 = ...;

// Use runAfterEither()

future1.thenCombine(future2, (result1, result2) -> {

// Main CompletableFuture has completed

}).runAfterEither(() -> {

// Either CompletableFuture has completed

});

10. How do you use orTimeout() to specify a timeout for a CompletableFuture?

You can use orTimeout() to specify a timeout for a CompletableFuture:

CompletableFuture future = ...;

// Specify a 1-second timeout

String result = future.orTimeout(1000, TimeUnit.MILLISECONDS).get();

I hope these questions are helpful for your Java CompletableFuture interview.