Q1. What is the result of attempting to compile and run the following Java code snippet?
final class FinalClass {
final int finalField;
FinalClass() {
finalField = 10;
}
final void finalMethod() {
System.out.println("Final method.");
}
}
class Extension extends FinalClass { // Line 1
void finalMethod() { // Line 2
System.out.println("Attempting to override.");
}
}
- A) Compiles and prints “Final method.”
- B) Compilation fails due to an attempt to extend a final class at Line 1.
- C) Compilation fails due to an attempt to override a final method at Line 2.
- D) Compiles and prints “Attempting to override.”
Answer: B) Compilation fails due to an attempt to extend a final class at Line 1.
Q2. Consider the following code snippet. What is the potential problem?
class Counter {
private int count = 0;
void increment() {
count++;
}
int getCount() {
return count;
}
}
- A) There is no problem with the code.
- B) The
increment
the method should be synchronized to prevent race conditions. - C) The
getCount
method should return a long instead of an int. - D) The
count
variable should be marked as volatile.
Answer: B) The increment
the method should be synchronized to prevent race conditions.
Q3. What does the following code print?
public class ThreadExample extends Thread {
public void run() {
for(int i = 0; i < 3; i++) {
System.out.print(i + "..");
}
}
public static void main(String[] args) {
ThreadExample t = new ThreadExample();
t.start();
System.out.print("Done");
}
}
- A) 0..1..2..Done
- B) Done0..1..2..
- C) 0..Done1..2..
- D) The output cannot be determined.
Answer: D) The output cannot be determined.
Q4. Which statement about the following code is true?
class BankAccount {
private double balance;
synchronized void deposit(double amount) {
balance += amount;
}
synchronized double getBalance() {
return balance;
}
}
- A) The code is not thread-safe and will result in a race condition.
- B) The code is thread-safe and will not result in a race condition.
- C) Only the
deposit
method should be synchronized. - D) The
balance
variable should be marked as volatile.
Answer: B) The code is thread-safe and will not result in a race condition.
Q5. What is the primary purpose of the ConcurrentHashMap
class in Java?
- A) To allow multiple threads to write to a map without synchronization.
- B) To prevent all access to the map while one thread is writing.
- C) To replace the
HashMap
class for better performance. - D) To ensure the order of elements in the map.
Answer: A) To allow multiple threads to write to a map without synchronization.
Q6. What is the result of executing the following code snippet?
public class Counter implements Runnable {
private static int count = 0;
public synchronized void run() {
count++;
System.out.println(count);
}
public static void main(String[] args) {
Thread t1 = new Thread(new Counter());
Thread t2 = new Thread(new Counter());
t1.start();
t2.start();
}
}
- A) The program prints “1” and “2” in an unpredictable order.
- B) The program may print “1” twice.
- C) The program prints “1” and “2” in the order of thread execution.
- D) Compilation fails.
Q7. Consider the following Java code snippet. What will it output?
final int[] values = {1, 2, 3};
values[0] = 10;
System.out.println(values[0]);
- A) 1
- B) 10
- C) Compilation error
- D) An exception at runtime
Answer: B) 10
Explanation: The final
keyword when applied to a variable means that the reference itself cannot be changed to point to another array or object, but the contents of the array or the fields of the object can still be modified. In this case, values
is a reference to an array of integers. While we cannot assign a new array to values
after its declaration, we can modify the elements of the array it references. Hence, the setting values[0] = 10
is valid and the output will be “10”.
Q8. Which statement is true about the synchronized keyword in Java?
- A) It can only be applied to methods.
- B) It ensures that only one thread can execute a block of code at a time.
- C) It automatically locks on the class’s
this
object when applied to static methods. - D) It increases the performance of multithreaded applications.
Answer: B) It ensures that only one thread can execute a block of code at a time.
Explanation: The synchronized
keyword can be used to mark methods or blocks of code so that only one thread can access them at any given time for any given instance of a class. This is crucial for preventing race conditions when multiple threads might change the same data concurrently. It does not inherently lock on the class’s this
object when applied to static methods; instead, it locks on the Class
object that represents the class being synchronized if the method is static.
Q9. What is the purpose of the volatile
keyword in Java?
- A) To make the class thread-safe
- B) To ensure that updates to a variable are propagated predictably to other threads
- C) To lock a variable for exclusive access by a thread
- D) To declare a variable as immutable
Answer: B) To ensure that updates to a variable are propagated predictably to other threads.
Explanation: The volatile
keyword is used to indicate that a variable’s value will be modified by different threads. Declaring a variable volatile
ensures that any thread that reads the variable will see the most recent write to that variable. This is a light form of synchronization, suitable for variables that are accessed by multiple threads but not involved in compound operations (like increment).
Q10. Given the following code, identify the line that could cause a race condition.
public class Counter {
private int count = 0;
public void increment() {
count++; // Line 1
}
public int getCount() {
return count; // Line 2
}
}
- A) Line 1
- B) Line 2
- C) Both Line 1 and Line 2
- D) Neither Line 1 nor Line 2
Answer: C) Both Line 1 and Line 2
Explanation: A race condition can occur when multiple threads access shared data and try to change it at the same time. In this example, both the increment operation (count++
) and the read operation (return count
) could be involved in a race condition if they are accessed by multiple threads simultaneously without proper synchronization, leading to inconsistent views of the value of count
..
Q11. Why are immutable objects considered inherently thread-safe in Java?
- A) Because their state cannot change after construction
- B) Because they use synchronization internally
- C) Because they can only hold primitive data types
- D) Because they are stored in the stack rather than the heap
Answer: A) Because their state cannot change after construction.
Explanation: Immutable objects are thread-safe because their state cannot be changed after they are constructed. This means that they can be shared between threads without the need for synchronization, as there is no risk of one thread modifying the state in a way that affects another thread.
Q12. Which Java Concurrency utility is best suited for managing a set of threads that perform various tasks asynchronously?
- A) Volatile variables
- B) Synchronized blocks
- C) Executors framework
- D)
java.util.concurrent.Semaphore
Answer: C) Executors framework
Explanation: The Executors framework is part of the java.util.concurrent
package and provides a higher-level replacement for working directly with threads. It is specifically designed to manage a pool of threads and execute asynchronous tasks. The framework simplifies the process of assigning tasks to threads and managing their lifecycle.
Q13. Consider the following code snippet. Which modification makes the LazyInitRace
class thread-safe?
public class LazyInitRace {
private ExpensiveObject instance = null;
public ExpensiveObject getInstance() {
if (instance == null)
instance = new ExpensiveObject();
return instance;
}
}
- A) Adding
synchronized
keyword to thegetInstance()
method - B) Declaring
instance
variable asvolatile
- C) Using
java.util.concurrent.locks.Lock
around the instance check and creation - D) All of the above
Answer: D) All of the above
Q14. What is the correct way to handle an interrupted exception in a thread’s run method?
- A) Ignore the exception
- B) Log the exception and exit the method
- C) Re-interrupt the thread and exit the method
- D) Throw a
RuntimeException
Answer: C) Re-interrupt the thread and exit the method
Q15. Which of the following operations is atomic and does not require synchronization?
- A) Reading and writing to a
volatile
long variable on a 32-bit JVM - B) Incrementing a
long
variable with++
- C) Setting a reference to a new object
- D) Reading and writing to a non-volatile
long
variable
Answer: C) Setting a reference to a new object